Aztec

NAME

Date::Calendar::Aztec - conversions from / to the Aztec calendar

SYNOPSIS


use Date::Calendar::Aztec;
my Date                  $d-greg  .= new(2020, 6, 20);
my Date::Calendar::Aztec $d-aztec .= new-from-date($d-greg);

say "{.tonalpohualli} {.xiuhpohualli}" with $d-aztec;
# --> 12 Tecpatl 20 Teotleco
$d-aztec.locale = 'en';
say "{.tonalpohualli} {.xiuhpohualli}" with $d-aztec;
# --> 12 Flint 20 God arrives

And in the other direction


use Date::Calendar::Aztec;
my Date $reference  .= new(2020, 1, 1);
my Date::Calendar::Aztec
        $d-aztec .= new(month           => 13
                     ,  day             => 20
                     ,  clerical-index  => 18
                     ,  clerical-number => 12
                     ,  on-or-after     => $reference);
my Date $d-greg = $d-aztec.to-date('Date');
say $d-greg;
# --> 2020-06-20

Conversion while paying attention to sun rise and sun set:


use Date::Calendar::Strftime;
use Date::Calendar::Gregorian;
use Date::Calendar::Aztec;

my Date::Calendar::Gregorian $d-gr;
my Date::Calendar::Aztec     $d-az;

$d-gr .= new('2024-11-13', daypart => before-sunrise());
$d-az .= new-from-date($d-gr);
say $d-az.strftime("%V %A %e %B");
# -->  "7 Coatl 1 Tlacaxipehualiztli"

$d-gr .= new('2024-11-13', daypart => daylight());
$d-az .= new-from-date($d-gr);
say $d-az.strftime("%V %A %e %B");
# -->  "7 Coatl 2 Tlacaxipehualiztli"

$d-gr .= new('2024-11-13', daypart => after-sunset());
$d-az .= new-from-date($d-gr);
say $d-az.strftime("%V %A %e %B");
# -->  "8 Miquiztli 2 Tlacaxipehualiztli"

DESCRIPTION

Date::Calendar::Aztec is a class that implements the Aztec calendars (tonalpohualli and xiuhpohualli).

This class uses the Alfonso Caso correlation. Another class uses the Francisco Cortes correlation, see Date::Calendar::Aztec::Cortes.

Aztecs used two different calendars, the civil calendar or "xiuhpohualli" and the clerical calendar or "tonalpohualli".

The civil calendar is organized like other calendars, with days grouped in months grouped in years. The difference with other calendars is that the months last 20 days each, not around 30, and there are 18 months, not 12. In addition, there are 5 additional days (Nemontemi), but no leap days are defined.

A last difference with other calendars is that years are not numbered.

The clerical calendar consists of two simultaneous cycles, the first one with numbers 1 to 13, the second one with 20 names. This gives a clerical year of 260 days.

METHODS

Object Creation

new

The new method can be called either with plain English keywords or with Nahuatl keywords. Here is the equivalence between English parameters and Nahuatl parameters.

month            xiuhpohualli-index
  day              xiuhpohualli-number
  clerical-index   tonalpohualli-index
  clerical-number  tonalpohualli-number

You should add a reference date (from the core Date class or from any Class::Calendar::xxx class), tagged with a relationship before, on-or-before, after, on-or-after or nearest. The reason why is explained in the Issues chapter, Rollover subchapter below. By default, the new method will use:


  nearest => Date.today,

In addition, you can provide the optional parameters locale and daypart. By default, they will be 'nah' for Nahuatl and daylight. Other possible values for the locale are 'en' and 'fr', other possible values for daypart are before-sunrise and after-sunset.

Examples:


use Date::Calendar::Strftime;
use Date::Calendar::Aztec;
my  Date::Calendar::Aztec $d-aztec;

$d-aztec .= new(month           => 3
             ,  day             => 2
             ,  clerical-index  => 6
             ,  clerical-number => 8
             ,  daypart         => after-sunset()
             ,  locale          => 'fr'
             ,  on-or-after     => Date.new('2001-01-01'));
say $d-aztec.strftime("%V %A %e %B");
# --> "8 Mort  2 Écorchement des hommes"

$d-aztec .= new(xiuhpohualli-index   =>  7
             ,  xiuhpohualli-number  =>  1
             ,  tonalpohualli-index  => 19
             ,  tonalpohualli-number =>  3
             ,  daypart              => daylight()
             ,  before               => Date.new('2050-01-01')
             ,  locale               => 'en');
say $d-aztec.strftime("%V %A %e %B");
# --> "3 Rain  1 Eating bean soup"

new-from-date

Build an Aztec 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.

If the origin object has a locale attribute, it is not copied.

Example:


use Date::Calendar::Strftime;
use Date::Calendar::Maya;
use Date::Calendar::Aztec;

my  Date::Calendar::Maya  $d-maya;
my  Date::Calendar::Aztec $d-aztec;

$d-maya .= new(long-count => '13.0.0.0.0'
            ,  daypart    => before-sunrise()
            ,  locale     => 'en');

$d-aztec .= new-from-date($d-maya);
$d-aztec.locale = $d-maya.locale;
say $d-aztec.strftime("%V %A %e %B");
# --> "4 Flower 16 1-vigil"

new-from-daycount

Build an Aztec date from the Modified Julian Day number and from the daypart parameter (optional, defaults to daylight).

Attribute getters

month

The numeric equivalent of the xiuhpohualli name.

For strftime, use the %m specifier.

month-name, xiuhpohualli-name

The name part of the civil calendar (xiuhpohualli). Its value depends on the value of the locale attribute.

For strftime, use the %B specifier.

day, xiuhpohualli-number

The numeric part of the civil calendar (xiuhpohualli), 1 to 20.

For strftime, use the %d or %e specifier.

xiuhpohualli

A string merging the numeric part and the name part of the civil calendar (xiuhpohualli). Its value depends on the value of the locale attribute.

No single strftime specifier, you have to mix %B with %d.

clerical-number, tonalpohualli-number

The numeric part of the clerical calendar (tonalpohualli).

For strftime, use the %V specifier.

clerical-name, tonalpohualli-name

The name part of the clerical calendar (tonalpohualli). Its value depends on the value of the locale attribute.

For strftime, use the %A specifier.

clerical-index, tonalpohualli-index

The numeric equivalent of the name part of the clerical calendar (tonalpohualli), 1 to 20.

For strftime, use the %u specifier.

tonalpohualli

A string merging the numeric part and the name part of the clerical calendar (tonalpohualli). Its value depends on the value of the locale attribute.

No single strftime specifier, you have to mix %V with %u.

year-bearer-number, year-bearer-index, year-bearer-name, year-bearer

The year bearer is a tonalpohualli date which is shared by all dates from a given "1 Tititl" to the next "5 Nemontemi" 364 days later. So we may consider that it sort of names the xiuhpohualli year. Yet it cannot define unambiguously the year, since it cycles every 52 xiuhpohualli years (a calendar round).

These four methods define the year bearer. Their names are similar to the clerical-xxx and the tonalpohualli-xxx methods, because the year bearer is a tonalpohualli date.

For strftime, use the %Y or %G specifier to print the year bearer (number and name).

gist

Print the numeric values for the civil and clerical calendars.

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 abbreviation of the language used for names. Actually, this attribute is read-write. You can create a date object with a first locale and then change it to another locale.

For the moment, the allowed values are 'nah' for Nahuatl, 'en' for English and 'fr' for French.

strftime

This method gives a string containing several attributes listed above. It is similar to the homonymous function in other languages. See the strftime Specifiers paragraph below.

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 "11 Calli 5 Quecholli" to the French Revolutionary calendar, you can code:


use Date::Calendar::Aztec;
use Date::Calendar::FrenchRevolutionary;

my  Date::Calendar::Aztec               $d-orig;
my  Date::Calendar::FrenchRevolutionary $d-dest-push;
my  Date::Calendar::FrenchRevolutionary $d-dest-pull;

$d-orig .= new(month => 15, day => 5, clerical-number => 11, clerical-index => 3);
$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;

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 Date to any other class other than Date, use the style you prefer. This includes Date::Calendar::Gregorian, a child class to the core class Date.

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 Specifiers

Designer's Notes

The Aztec calendar is not like the others, based on year-month-day triplets. So defining which data will be printed by which strftime specifier is not obvious. Let us see what can be done with the principle of least surprise.

At least, the common calendar (xiuhpohualli) is based on month-day pairs. And the months have an unambiguous numeric representation. So we can easily define what will be printed by %B, %d, %e, %f and %m. The tonalpohualli names (Cipactli, Ehecatl...) run through a cycle, just as the week days (Monday, Tuesday...), so it is natural to assimilate both notions, even if the cycle lengths are different: 20 in the first case, 7 in the latter case. So specifiers %A and %u are cared for.

That is all for the obvious equivalences. Now, we can define other specifiers by shoe-horning a Gregorian concept into them. For example the %V specifier. It represents the week number for the Gregorian calendar, or how many 7-day cycles have elapsed since the beginning of the year. This is not interesting for the Aztec calendar, because a tonalpohualli 20-name cycle coincidates with a xiuhpohualli 20-day month. Another way to describe the %V specifier is "the number which is usually printed associated to %u (in the ISO date format)". Since %u gives the tonalpohualli index (i.e. the numeric form of the tonalpohualli name), %V should give the tonalpohualli number.

What about the year numbers %Y and %G? The %Y specifier can be described as "the specifier which keeps the same value from 1st January to 31st December". In the Aztec calendar, which notion keeps the same value from 1 Izcalli until 5 Nemontemi? The year bearer which, therefore, can uniquely identify a year, within some limits. More precisely, within a calendar round (52 years), the year bearer is a unique identifier for the xiuhpohualli year. So the %Y specifier will print the year bearer. On the other hand, identifying the year with its year bearer is flawed with a rollover problem similar to the Y2K bug, except that it occurs every 52 years instead of every 100 years. So it may be better to associate the year bearer with the %y specifier, which can be defined as the "Y2K-flawed year specifier". For the Gregorian calendar, the %G specifier prints the year number for the week-based "ISO" date. There is no week-related "ISO" date in the Aztec calendar, so %G will print the same as %Y.

And the %F specifier? For the Maya calendar, I have decided to use it to print the long count. But the Aztec calendar has nothing like the Maya long count. So the %F specifier will not print a date value, it will be printed without change in the output string.

Specifiers

%A

The tonalpohualli name, similar to the name of the day of week.

%B

The xiuhpohualli name, similar to a month name.

%d

The xiuhpohualli number, which can be seen as the numeric form of the day of the month (range 01 to 20).

%e

Like %d, the xiuhpohualli number or day of the month as a decimal number, but a leading zero is replaced by a space.

%f

The numeric form of the xiuhpohualli name, or month as a decimal number (1 to 19). Unlike %m, a leading zero is replaced by a space.

%G

The year bearer.

%j

The day of the year as a decimal number (range 001 to 365).

%m

The numeric form of the xiuhpohualli name, or the month, as a two-digit decimal number (range 01 to 19), including a leading zero if necessary.

%n

A newline character.

%Ep

Gives a 1-char string representing the day part:

  • ☾ or U+263E before sunrise,

  • ☼ or U+263C during daylight,

  • ☽ or U+263D after 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 tonalpohualli index, that is the 1..20 numeric equivalent of the tonalpohualli name.

%V

The tonalpohualli number.

%Y

The year bearer.

%%

A literal `%' character.

Modifiers

A complete 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, these "E" and "O" modifiers are ignored.

ISSUES

The First Month of the Civil Year

The website https://www.azteccalendar.com gives three options: the Alfonso Caso correlation, the Alfonso Caso correlation with Nicholson's alignment and the Francisco Cortes correlation. With the plain Caso correlation and with the Cortes correlation, the months follow this sequence:

  • 18 Tititl

  • 19 Nemontemi

  • 1 Izcalli

  • 2 Atlcahualo

while the Caso correlation with Nicholson's alignment uses this sequence:

  • 17 Tititl

  • 18 Izcalli

  • 19 Nemontemi

  • 1 Atlcahualo

I have decided to discard Nicholson's alignment and to implement only the plain Alfonso Caso correlation (this class) and the Francisco Cortes correlation (see Date::Calendar::Aztec::Cortes).

Definition of the Day

Reingold and Dershowitz give some hints about the definitions of days in the Maya calendars, but none on the definitions in the Aztec calendars. I have use the programmer-friendly option of reusing the same definitions as the Maya ones (which are still suppositions and not hard statements):

  • xiuhpohualli days are sunrise to sunrise

  • tonalpohualli days are sunset to sunset

Rollover

The Aztecs had nothing like the Mayas' long count or like other calendars' year numbers. By combining the civil calendar with the clerical calendar, we get different combinations for about 52 years. This period is called the "calendar round". So when given an Aztec date with the four values (tonalpohualli number and name, xiuhpohualli number and name), you cannot define a unique Gregorian date equivalent to this Aztec date. The Gregorian date 52 years later (or 104, or 156) and the Gregorian date 52 years earlier (or 104 or...) also correspond to this Aztec date.

For this reason, Aztec dates are created with a reference date from another calendar, so the module will compute which is the first Aztec date on or after the reference date and with the requested month, name, clerical index and clerical number (or "on or before the reference date", or "nearest to the reference date", etc). This allows the module to compute an attribute daycount, which will be used when converting an Aztec date to another calendar.

The Name of Month 2

Another issue it month number 2, between Izcalli and Tlacaxipehualiztli. Most sources give the name "Atlcahualo", but the website https://www.azteccalendar.com gives the name "Cuauhuitlehua".

Year Bearers

For a given civil year, the year bearer is the clerical number + name of new year's day, or possibly of new year's eve. In other words, it is either the tonalpohualli number + name of 1 Izcalli or the tonalpohualli number + name of 5 Nemontemi. Yet, when we browse https://www.azteccalendar.com, we find that the year bearer has the tonalpohualli name of the previous 5 Nemontemi and the tonalpohualli number of the previous 1 Nemontemi. Is this a bug in this website or is it a very convoluted definition of the year bearer, although the real definition? I have decided to stick with it.

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 between calendars in which the day is defined as sunset-to-sunset and calendars in which the day is defined as midhnight-to-midnight. 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::MayaAztec: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::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::Julian or https://github.com/jforget/raku-Date-Calendar-Julian

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::Persian or https://github.com/jforget/raku-Date-Calendar-Persian

Date::Calendar::CopticEthiopic or https://github.com/jforget/raku-Date-Calendar-CopticEthiopic

Date::Calendar::Bahai or https://github.com/jforget/raku-Date-Calendar-Bahai

Date::Calendar::FrenchRevolutionary or https://github.com/jforget/raku-Date-Calendar-FrenchRevolutionary

Other Software

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 (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. ISBN 978-0-521-70238-6 for the third edition.

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 (website no longer responding).

Histoire comparée des numérations écrites by Geneviève Guitel, published by Flammarion (Nouvelle bibliothèque scientifique), ISBN 2-08-21114-0

Internet

https://en.wikipedia.org/wiki/Aztec_calendar

https://www.britannica.com/topic/Aztec-calendar

https://www.azteccalendar.com/

http://research.famsi.org/date_mayaLC.php

https://icalendrier.fr/calendriers-saga/calendriers/azteque/ (in French)

AUTHOR

Jean Forget <J2N-FORGET at orange dot fr>

COPYRIGHT AND LICENSE

Copyright (c) 2020, 2023, 2024 Jean Forget

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

Date::Calendar::MayaAztec v0.1.0

conversions from/to the Maya calendar and from/to the Aztec calendar

Authors

  • Jean Forget

License

Artistic-2.0

Dependencies

Date::Calendar::Strftime

Test Dependencies

Provides

  • Date::Calendar::Aztec
  • Date::Calendar::Aztec::Common
  • Date::Calendar::Aztec::Cortes
  • Date::Calendar::Aztec::Names
  • Date::Calendar::Maya
  • Date::Calendar::Maya::Astronomical
  • Date::Calendar::Maya::Common
  • Date::Calendar::Maya::Names
  • Date::Calendar::Maya::Spinden
  • Date::Calendar::MayaAztec

Documentation

The Camelia image is copyright 2009 by Larry Wall. "Raku" is a trademark of the Yet Another Society. All rights reserved.

Built with Podlite — the markup and publishing tools behind this site.