Julian
NAME
Date::Calendar::Julian - Converting from / to the Julian calendar
SYNOPSIS
Converting a Gregorian date (e.g. 15 February 2020) into Julian
use Date::Calendar::Julian;
my Date $feb15-grg;
my Date::Calendar::Julian $palindrome-jul;
$feb15-grg .= new(2020, 2, 15);
$palindrome-jul .= new-from-date($feb15-grg);
say $palindrome-jul;
# --> 2020-02-02
$palindrome-jul.locale = 'nl';
say $palindrome-jul.strftime("%A %e %B %Y");
# --> zaterdag 2 februari 2020
my Str $s1 = $palindrome-jul.strftime("%Y%m%d");
if $s1 eq $s1.flip {
say "$s1 is a palindrome in YYYYMMDD format!";
}
$s1 = $palindrome-jul.strftime("%d%m%Y");
if $s1 eq $s1.flip {
say "$s1 is a palindrome in DDMMYYYY format!";
}
$s1 = $palindrome-jul.strftime("%m%d%Y");
if $s1 eq $s1.flip {
say "$s1 is a palindrome in MMDDYYYY format!";
}
Converting a Julian date (e.g. 1st August 2020) into Gregorian
use Date::Calendar::Julian;
my Date::Calendar::Julian $TPRC-Amsterdam-jul;
my Date $TPRC-Amsterdam-grg;
$TPRC-Amsterdam-jul .= new(year => 2020
, month => 8
, day => 1);
$TPRC-Amsterdam-grg = $TPRC-Amsterdam-jul.to-date;
say "The Perl and Raku conference was scheduled to end on ", $TPRC-Amsterdam-grg;
# --> The Perl and Raku conference was scheduled to end on 2020-08-14
Conversion with a calendar which defines days as sunset to sunset
use Date::Calendar::Strftime;
use Date::Calendar::Hebrew;
use Date::Calendar::Julian;
my Date::Calendar::Julian $d-ju;
my Date::Calendar::Hebrew $d-he;
$d-ju .= new(year => 2024, month => 10, day => 31, daypart => before-sunrise());
$d-he .= new-from-date($d-ju);
say $d-he.strftime("%A %d %B %Y");
# ---> "Yom Reviʻi 12 Heshvan 5785"
$d-ju .= new(year => 2024, month => 10, day => 31, daypart => daylight());
$d-he .= new-from-date($d-ju);
say $d-he.strftime("%A %d %B %Y");
# ---> "Yom Reviʻi 12 Heshvan 5785" again
$d-ju .= new(year => 2024, month => 10, day => 31, daypart => after-sunset());
$d-he .= new-from-date($d-ju);
say $d-he.strftime("%A %d %B %Y");
# ---> "Yom Chamishi 13 Heshvan 5785" instead of "Yom Reviʻi 12 Heshvan 5785"
DESCRIPTION
Date::Calendar::Julian is a class representing the Julian calendar, the forerunner of the Gregorian calendar. The module allows you to convert Julian dates into other calendars and to convert other dates into the Julian calendar.
The Julian differ from the Gregorian calendar only on the leap year rule. For the Julian calendar, every multiple of 4 is a leap year. There is no adjustment on a century year.
This module adopts a simplified point of view about the Julian calendar. Except for the leap year rule, everything in the module is similar to the Gregorian calendar. Days are midnight to midnight, weeks are Monday to Sunday, years are 1st January to 31st December. Historically, the rules were not as rigid as that, especially the rule defining the beginning of the year.
Another simplification is that there is a year zero. Generally, people
consider that the day before 1st January 1 AD is 31st December 1 BC.
But another point of view is possible, by deciding that the numbering
of the years follows the rule of integers and that the number just
before 1 is 0, not -1 (or 1 BC). This is the point of view adopted by
this module. And also by the core module Date (which implements the
Gregorian calendar).
Constructors
new
Create a Julian date by giving the year, month and day numbers and optionally the locale and the daypart.
new-from-date
Build a Julian date by cloning an object from another class. This
other class can be the core class Date or any
Date::Calendar::xxx class with a daycount method and
hopefully a daypart method.
This method does not allow a locale build parameter. The object is
built with the default locale, 'en'.
new-from-daycount
Build a Julian date from the Modified Julian Day number and from the
daypart parameter (optional).
This method does not allow a locale build parameter. The object is
built with the default locale, 'en'.
Accessors
gist
Gives a short string representing the date, in YYYY-MM-DD format.
year, month, day
The numbers defining the date.
daycount
The MJD (Modified Julian Date) number for the date.
daypart
A number indicating which part of the day. This number should be filled and compared with the following subroutines, with self-documenting names:
before-sunrise()
daylight()
after-sunset()
locale
The two-char string defining the locale used for the date. Use any
value allowed by the module Date::Names.
This attribute can be updated after build time.
month-name
The month of the date, as a string. This depends on the date's current locale.
month-abbr
The abbreviated month of the date.
Depending on the locale, it may be a 3-char string, a 2-char or a
short code of variable length. Please refer to the documentation of
Date::Names for the availability of mon3, mon2 and mona.
day-name
The name of the day within the week. It depends on the date's current locale.
day-abbr
The abbreviated day name of the date.
Depending on the locale, it may be a 3-char string, a 2-char string or
a short code of variable length. Please refer to the documentation of
Date::Names for the availability of dow3, dow2 and dowa.
day-of-week
The day of the week, as a number (1 for Monday, 7 for Sunday).
week-number
The number of the week within the year, 1 to 52 or 1 to 53. Similar to the "ISO date" as defined for Gregorian date. Week number 1 is the Mon→Sun span that contains the first Thursday of the year, week number 2 is the Mon→Sun span that contains the second Thursday of the year and so on.
week-year
Mostly similar to the year attribute. Yet, the last days of the
year and the first days of the following year can be sort-of
transferred to the other year. The week-year attribute reflects
this transfer. While the real year always begins on 1st January and
ends on the 31st December, the week-year always begins on Monday
and it always ends on Sunday.
day-of-year
How many days since the beginning of the year. 1 to 365 on normal years, 1 to 366 on leap years.
daycount
The Modified Julian Day Number (a day-only scheme based on 17 November 1858).
Other Methods
to-date
Clones the date into a core class Date object or some
Date::Calendar::xxx compatible calendar class. The target class
name is given as a positional parameter. This parameter is optional,
the default value is "Date" for the Gregorian calendar.
To convert a date from a calendar to another, you have two conversion styles, a "push" conversion and a "pull" conversion. For example, while converting "1st February 2020" to the French Revolutionary calendar, you can code:
use Date::Calendar::Julian;
use Date::Calendar::FrenchRevolutionary;
my Date::Calendar::Julian $d-orig;
my Date::Calendar::FrenchRevolutionary $d-dest-push;
my Date::Calendar::FrenchRevolutionary $d-dest-pull;
$d-orig .= new(year => 2020
, month => 2
, day => 1);
$d-dest-push = $d-orig.to-date("Date::Calendar::FrenchRevolutionary");
$d-dest-pull .= new-from-date($d-orig);
say $d-orig, ' ', $d-dest-push, ' ', $d-dest-pull;
# --> "2020-02-01 0228-05-26 0228-05-26"
And the dates $d-dest-push and $d-dest-pull are identical.
When converting from the core class Date, use the pull style.
When converting to the core class Date, use the push style. When
converting from any class other than the core class Date to any
other class other than the core class Date, use the style you
prefer. This includes the class Date::Calendar::Gregorian
inheriting from Date and implementing the Gregorian calendar.
Even if both calendars use a locale attribute, when a date is
created by the conversion of another date, it is created with the
default locale. If you want the locale to be transmitted in the
conversion, you should add a line such as:
$d-dest-pull.locale = $d-orig.locale;
strftime
This method is very similar to the homonymous functions you can find
in several languages (C, shell, etc). It also takes some ideas from
printf-similar functions. For example
$df.strftime("%04d blah blah blah %-25B")
will give the day number padded on the left with 2 or 3 zeroes to
produce a 4-digit substring, plus the substring " blah blah blah ",
plus the month name, padded on the right with enough spaces to produce
a 25-char substring. Thus, the whole string will be at least 42 chars
long.
A strftime specifier consists of:
A percent sign,
An optional minus sign, to indicate on which side the padding occurs. If the minus sign is present, the value is aligned to the left and the padding spaces are added to the right. If it is not there, the value is aligned to the right and the padding chars (spaces or zeroes) are added to the left.
An optional zero digit, to choose the padding char for right-aligned values. If the zero char is present, padding is done with zeroes. Else, it is done wih spaces.
An optional length, which specifies the minimum length of the result substring.
An optional
"E"or"O"modifier. On some older UNIX system, these were used to give the extended or localized version of the date attribute. Here, they rather give alternate variants of the date attribute. Not used with the Julian calendar.A mandatory type code.
The allowed type codes are:
- %a
The day of week name, abbreviated to 3 chars.
- %A
The full day of week name.
- %b
The abbreviated month name.
- %B
The full month name.
- %d
The day of the month as a decimal number (range 01 to 31).
- %e
Like %d, the day of the month as a decimal number, but a leading
zero is replaced by a space.
- %f
The month as a decimal number (1 to 12). Unlike %m, a leading zero
is replaced by a space.
- %F
Equivalent to %Y-%m-%d (the ISO 8601 date format)
- %G
The "week year" as a decimal number. Mostly similar to %Y, but it
may differ on the very first days of the year or on the very last
days. Analogous to the year number in the so-called "ISO date" format
for Gregorian dates.
- %j
The day of the year as a decimal number (range 001 to 366).
- %L
Redundant with %Y and strongly discouraged: the year number.
Since 2024 and the release of Date::Calendar::Strfrtime version
0.0.4, this strftime specifier is deprecated.
- %m
The month as a two-digit decimal number (range 01 to 12), including a leading zero if necessary.
- %n
A newline character.
- %Ep
Gives a 1-char string representing the day part:
☾orU+263Ebefore sunrise,☼orU+263Cduring daylight,☽orU+263Dafter sunset.
Rationale: in C or in other programming languages, when strftime
deals with a date-time object, the day is split into two parts, before
noon and after noon. The %p specifier reflects this by giving a
"AM" or "PM" string.
The 3-part splitting in the Date::Calendar::xxx may be
considered as an alternate splitting of a day. To reflect this in
strftime, we use an alternate version of %p, therefore %Ep.
- %t
A tab character.
- %u
The day of week as a 1..7 number.
- %V
The week number as defined above, similar to the week number in the so-called "ISO date" format for Gregorian dates.
- %Y
The year as a decimal number.
- %%
A literal `%' character.
PROBLEMS AND KNOWN ISSUES
Security issues
As explained in the Date::Calendar::Strftime documentation, please
ensure that format-string passed to strftime comes from a trusted
source. Failing that, the untrusted source can include a outrageous
length in a strftime specifier and this will drain your PC's RAM
very fast.
Relations with :ver<0.0.x> classes and with core class Date
Version 0.1.0 (and API 1) was introduced to ease the conversions with
other calendars in which the day is defined as sunset-to-sunset. If
all Date::Calendar::xxx classes use version 0.1.x and API 1, the
conversions will be correct. But if some Date::Calendar::xxx
classes use version 0.0.x and API 0, there might be problems.
A date from a 0.0.x class has no daypart attribute. But when "seen"
from a 0.1.x class, the 0.0.x date seems to have a daypart
attribute equal to daylight. When converted from a 0.1.x class to a
0.0.x class, the date may just shift from after-sunset (or
before-sunrise) to daylight, or it may shift to the daylight
part of the prior (or next) date. This means that a roundtrip with
cascade conversions may give the starting date, or it may give the
date prior or after the starting date.
If you install <Date::Calendar::Julian:ver<0.1.0>>, why would you
refrain from upgrading other Date::Calendar::xxxx classes? So
actually, this issue applies mainly to the core class Date, because
you may prefer avoiding the installation of
Date::Calendar::Gregorian.
Time
This module and the Date::Calendar::xxx associated modules are
still date modules, they are not date-time modules. The user has to
give the daypart attribute as a value among before-sunrise,
daylight or after-sunset. There is no provision to give a HHMMSS
time and convert it to a daypart parameter.
SEE ALSO
Raku Software
Date::Names or https://github.com/tbrowder/Date-Names
Date::Calendar::Strftime or https://github.com/jforget/raku-Date-Calendar-Strftime
Date::Calendar::Gregorian or https://github.com/jforget/raku-Date-Calendar-Gregorian
Date::Calendar::Hebrew or https://github.com/jforget/raku-Date-Calendar-Hebrew
Date::Calendar::Hijri or https://github.com/jforget/raku-Date-Calendar-Hijri
Date::Calendar::CopticEthiopic or https://github.com/jforget/raku-Date-Calendar-CopticEthiopic
Date::Calendar::MayaAztec or https://github.com/jforget/raku-Date-Calendar-MayaAztec
Date::Calendar::FrenchRevolutionary or https://github.com/jforget/raku-Date-Calendar-FrenchRevolutionary
Date::Calendar::Persian or https://github.com/jforget/raku-Date-Calendar-Persian
Date::Calendar::Bahai or https://github.com/jforget/raku-Date-Calendar-Bahai
Perl 5 Software
Other Software
date(1), strftime(3)
calendar/cal-julian.el in emacs or xemacs.
CALENDRICA 4.0 -- Common Lisp, which can be download in the "Resources" section of https://www.cambridge.org/us/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition?format=PB&isbn=9781107683167 (Actually, I have used the 3.0 version which is not longer available)
Books
Calendrical Calculations (Third or Fourth Edition) by Nachum Dershowitz and Edward M. Reingold, Cambridge University Press, see http://www.calendarists.com or https://www.cambridge.org/us/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition?format=PB&isbn=9781107683167.
La saga des calendriers, by Jean Lefort, published by Belin (Pour la Science), ISBN 2-90929-003-5 See https://www.belin-editeur.com/la-saga-des-calendriers (site not longer responding).
Le Calendrier, by Paul Couderc, published by Presses universitaires de France (Que sais-je ?), ISBN 2-13-036266-4 See https://catalogue.bnf.fr/ark:/12148/cb329699661.
AUTHOR
Jean Forget <J2N-FORGET at orange dot fr>
COPYRIGHT AND LICENSE
Copyright (c) 2020, 2021, 2024 Jean Forget
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.