CopticEthiopic
NAME
Date::Calendar::CopticEthiopic - conversions from / to the Coptic calendar and from / to the Ethiopic calendar
SYNOPSIS
Converting a Gregorian date to both Coptic and Ethiopic
use Date::Calendar::Coptic;
use Date::Calendar::Ethiopic;
my Date $Perlcon-Riga-grg;
my Date::Calendar::Coptic $Perlcon-Riga-cop;
my Date::Calendar::Ethiopic $Perlcon-Riga-eth;
$Perlcon-Riga-grg .= new(2019, 8, 7);
$Perlcon-Riga-cop .= new-from-date($Perlcon-Riga-grg);
$Perlcon-Riga-eth .= new-from-date($Perlcon-Riga-grg);
say $Perlcon-Riga-cop.strftime("%A %e %B %Y");
#--> Peftoou 1 Mesori 1735
say $Perlcon-Riga-eth.strftime("%A %e %B %Y");
#--> Rob 1 Nähase 2011
Converting a Coptic date and an Ethiopic date to Gregorian
use Date::Calendar::Coptic;
use Date::Calendar::Ethiopic;
my Date::Calendar::Coptic $TPC-Pittsburgh-cop;
my Date::Calendar::Ethiopic $TPC-Pittsburgh-eth;
my Date $TPC-Pittsburgh-grg1;
my Date $TPC-Pittsburgh-grg2;
$TPC-Pittsburgh-cop .= new(year => 1735, month => 10, day => 9);
$TPC-Pittsburgh-grg1 = $TPC-Pittsburgh-cop.to-date;
say $TPC-Pittsburgh-cop.strftime("%e %B %Y = "), $TPC-Pittsburgh-grg1.gist;
#--> 9 Paoni 1735 = 2019-06-16
$TPC-Pittsburgh-eth .= new(year => 2011, month => 10, day => 14);
$TPC-Pittsburgh-grg2 = $TPC-Pittsburgh-eth.to-date;
say $TPC-Pittsburgh-eth.strftime("%e %B %Y = "), $TPC-Pittsburgh-grg2.gist;
#--> 14 Säne 2011 = 2019-06-21
Converting a date from Gregorian to Coptic and Ethiopic, while paying attention to the sunset:
use Date::Calendar::Strftime;
use Date::Calendar::Gregorian;
use Date::Calendar::Coptic;
use Date::Calendar::Ethiopic;
my Date::Calendar::Gregorian $d-grg;
my Date::Calendar::Coptic $d-cop;
my Date::Calendar::Ethiopic $d-eth;
$d-grg .= new('2024-11-13', daypart => before-sunrise());
$d-cop .= new-from-date($d-grg);
$d-eth .= new-from-date($d-grg);
say $d-cop.strftime("%A %e %B %Y"), $d-eth.strftime(" %A %e %B %Y");
# --> Peftoou 4 Hathor 1741 Rob 4 Ḫədar 2017
$d-grg .= new('2024-11-13', daypart => daylight());
$d-cop .= new-from-date($d-grg);
$d-eth .= new-from-date($d-grg);
say $d-cop.strftime("%A %e %B %Y"), $d-eth.strftime(" %A %e %B %Y");
# --> Peftoou 4 Hathor 1741 Rob 4 Ḫədar 2017 (again)
$d-grg .= new('2024-11-13', daypart => after-sunset());
$d-cop .= new-from-date($d-grg);
$d-eth .= new-from-date($d-grg);
say $d-cop.strftime("%A %e %B %Y"), $d-eth.strftime(" %A %e %B %Y");
# --> Ptiou 5 Hathor 1741 Hamus 5 Ḫədar 2017
DESCRIPTION
Date::Calendar::CopticEthiopic is a module distribution providing two classes, Date::Calendar::Coptic and Date::Calendar::Ethiopic. The corresponding calendars both derive from the ancient Egyptian calendar. In each, a year consists of 12 months with 30 days each, plus 5 or 6 additional days (epagomene) at the end of the year. Leap years occurs every fourth year, with no adjustment for century years. The calendars also define weeks which last for 7 days, beginning on sunday and ending on saturday.
METHODS
Constructors
new
Create a Coptic or Ethiopic date by giving the year, month and day
numbers, plus optionally the day part (before-sunrise, daylight
or after-sunset).
new-from-date
Build a Coptic or Ethiopic 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.
new-from-daycount
Build a Coptic or Ethiopic date from the Modified Julian Day number
and the daypart value.
Accessors
year, month, day
The numbers defining 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()
month-name
The month of the date, as a string.
month-abbr
The month of the date, as a 3-char string.
day-name
The name of the day within the week, as a string.
day-abbr
The name of the day within the week, as a 3-char string.
day-of-week
The number of the day within the week (1 for sunday / Tkyriakē / Ihud, 7 for saturday / Psabbaton / Kidamme).
week-number
The number of the week within the year, 1 to 52 (or even 53 on some years). Similar to the "ISO date" as defined for Gregorian date. Week number 1 is the Sun→Sat span that contains the first Wednesday / Peftoou / Rob of the year. This first week may start as soon as the 3rd epagomene day (or 4th on leap year) or as late as 4 Thout / Mäskäräm. Likewise, the last week of the year may end as soon as the 2nd epagomene day or it may last until 3rd Thout of the following year.
week-year
Mostly similar to the year attribute. Yet, as described for the
so-called "ISO-date" for the Gregorian calendar and as explained
above, 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 Thout / Mäskäräm and ends on the 5th (6th if leap) epagomene day,
the week-year always begins on Sunday / Tkyriakē / Ihud and it
always ends 364 or 371 days later on Saturday / Psabbaton / Kidamme.
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 MJD value (Modified Julian Date) for the date.
Other Methods
gist
Gives a short string representing the date, in YYYY-MM-DD format.
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 from the Coptic date "10 Thout 1736" to Ethiopic, you can code:
use Date::Calendar::Coptic;
use Date::Calendar::Ethiopic;
my Date::Calendar::Coptic $d-orig;
my Date::Calendar::Ethiopic $d-dest-push;
my Date::Calendar::Ethiopic $d-dest-pull;
$d-orig .= new(year => 1736
, month => 1
, day => 10);
$d-dest-push = $d-orig.to-date("Date::Calendar::Ethiopic");
$d-dest-pull .= new-from-date($d-orig);
say $d-orig, ' ', $d-dest-push, ' ', $d-dest-pull;
# --> 1736-01-10 2012-01-10 2012-01-10
And $d-dest-push and $d-dest-pull result in the same date.
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.
Please note that the class Date::Calendar::Gregorian can be used
instead of the core class Date to implement Gregorian dates. And
with this class, you can use both the push and the pull methods, just
like the other Date::Calendar::xxx classes.
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. By the way, you can drop the "at least" mention, because the
longest month name is 15-char long, so the padding will always occur
and will always include at least 10 spaces.
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.A mandatory type code.
The allowed type codes are:
- %a
The abbreviated day of week name.
- %A
The full day of week name.
- %b
The abbreviated month name.
- %B
The full month name.
- %c
The date-time, using the default format, as defined by the current locale.
- %d
The day of the month as a decimal number (range 01 to 30).
- %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 13). 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 %L and
%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
The year as a decimal number. Strictly similar to %Y and mostly
similar to %G.
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 13), 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. Strictly similar to %L and mostly
similar to %G.
- %%
A literal `%' character.
ISSUES, BUGS, ETC
I am no expert in the Sahidic (Coptic) language and in the Amharic (Ethiopic) language. I have copied / pasted names from free sources, but I am in no position to recognize which sources are authoritative or not. Also, I have kept the Latin script (although with some diacritics) and not the Coptic script.
Ethiopic or Ethiopian? Some English-speaking sources (see below) use Ethiopic, the others use Ethiopian. Since the first source I have read is Reingold's and Dershowitz' book, I have used the same term as them, Ethiopic.
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::CopticEthiopic: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
Internet
https://en.wikipedia.org/wiki/Coptic_calendar
https://en.wikipedia.org/wiki/Ethiopian_calendar
https://www.funaba.org/cc (website no longer works).
https://www.tondering.dk/claus/calendar.html - Claus Tøndering's calendar FAQ
https://www.ephemeride.com/calendrier/autrescalendriers/21/autres-types-de-calendriers.html (in French)
Raku Software
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::FrenchRevolutionary or https://github.com/jforget/raku-Date-Calendar-FrenchRevolutionary
Date::Calendar::Julian or https://github.com/jforget/raku-Date-Calendar-Julian
Date::Calendar::Hijri or https://github.com/jforget/raku-Date-Calendar-Hijri
Date::Calendar::MayaAztec or https://github.com/jforget/raku-Date-Calendar-MayaAztec
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-coptic.el in Emacs.
https://pypi.org/project/convertdate/ or https://convertdate.readthedocs.io/en/latest/modules/coptic.html
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
Books
Calendrical Calculations (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. (Actually, I have used the third edition which is not longer available, see pages 72 to 77)
La saga des calendriers, p 70-71, by Jean Lefort, published by Belin (Pour la Science), ISBN 2-90929-003-5 See https://www.belin-editeur.com/la-saga-des-calendriers (webpage no longer available).
AUTHOR
Jean Forget <J2N-FORGET at orange dot fr>
COPYRIGHT AND LICENSE
Copyright (c) 2019, 2020, 2024, 2025 Jean Forget
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.