Mayan calendar

Revision as of 02:10, 11 February 2022 by Rdm (talk | contribs) (J: slightly more concise)

The ancient Maya people had two somewhat distinct calendar systems.

Task
Mayan calendar
You are encouraged to solve this task according to the task description, using any language you may know.

In somewhat simplified terms, one is a cyclical calendar known as The Calendar Round, that meshes several sacred and civil cycles; the other is an offset calendar known as The Long Count, similar in many ways to the Gregorian calendar.

The Calendar Round

The Calendar Round has several intermeshing sacred and civil cycles that uniquely identify a specific date in an approximately 52 year cycle.

The Tzolk’in

The sacred cycle in the Mayan calendar round was called the Tzolk’in. The Tzolk'in has a cycle of 20 day names:

   Imix’
   Ik’
   Ak’bal
   K’an
   Chikchan
   Kimi
   Manik’
   Lamat
   Muluk
   Ok
   Chuwen
   Eb
   Ben
   Hix
   Men
   K’ib’
   Kaban
   Etz’nab’
   Kawak
   Ajaw

Intermeshed with the named days, the Tzolk’in has a cycle of 13 numbered days; 1 through 13. Every day has both a number and a name that repeat in a 260 day cycle.

For example:

   1 Imix’
   2 Ik’
   3 Ak’bal
   ...
   11 Chuwen
   12 Eb
   13 Ben
   1 Hix
   2 Men
   3 K’ib’
   ... and so on.

The Haab’

The Mayan civil calendar is called the Haab’. This calendar has 365 days per year, and is sometimes called the ‘vague year.’ It is substantially the same as our year, but does not make leap year adjustments, so over long periods of time, gets out of synchronization with the seasons. It consists of 18 months with 20 days each, and the end of the year, a special month of only 5 days, giving a total of 365. The 5 days of the month of Wayeb’ (the last month), are usually considered to be a time of bad luck.

Each month in the Haab’ has a name. The Mayan names for the civil months are:

   Pop
   Wo’
   Sip
   Sotz’
   Sek
   Xul
   Yaxk’in
   Mol
   Ch’en
   Yax
   Sak’
   Keh
   Mak
   K’ank’in
   Muwan
   Pax
   K’ayab
   Kumk’u
   Wayeb’ (Short, "unlucky" month)

The months function very much like ours do. That is, for any given month we count through all the days of that month, and then move on to the next month.

Normally, the day 1 Pop is considered the first day of the civil year, just as 1 January is the first day of our year. In 2019, 1 Pop falls on April 2nd. But, because of the leap year in 2020, 1 Pop falls on April 1st in the years 2020-2023.

The only really unusual aspect of the Haab’ calendar is that, although there are 20 (or 5) days in each month, the last day of the month is not called the 20th (5th). Instead, the last day of the month is referred to as the ‘seating,’ or ‘putting in place,’ of the next month. (Much like how in our culture, December 24th is Christmas Eve and December 31st is 'New-Years Eve'.) In the language of the ancient Maya, the word for seating was chum, So you might have:

   ...
   18 Pop (18th day of the first month)
   19 Pop (19th day of the first month)
   Chum Wo’ (20th day of the first month)
   1 Wo’ (1st day of the second month)
   ... and so on.

Dates for any particular day are a combination of the Tzolk’in sacred date, and Haab’ civil date. When put together we get the “Calendar Round.”

Calendar Round dates always have two numbers and two names, and they are always written in the same order:

   (1) the day number in the Tzolk’in
   (2) the day name in the  Tzolk’in
   (3) the day of the month in the Haab’
   (4) the month name in the Haab’

A calendar round is a repeating cycle with a period of just short of 52 Gregorian calendar years. To be precise: it is 52 x 365 days. (No leap days)

Lords of the Night

A third cycle of nine days honored the nine Lords of the Night; nine deities that were associated with each day in turn. The names of the nine deities are lost; they are now commonly referred to as G1 through G9. The Lord of the Night may or may not be included in a Mayan date, if it is, it is typically just the appropriate G(x) at the end.

The Long Count

Mayans had a separate independent way of measuring time that did not run in cycles. (At least, not on normal human scales.) Instead, much like our yearly calendar, each day just gets a little further from the starting point. For the ancient Maya, the starting point was the ‘creation date’ of the current world. This date corresponds to our date of August 11, 3114 B.C. Dates are calculated by measuring how many days have transpired since this starting date; This is called “The Long Count.” Rather than just an absolute count of days, the long count is broken up into unit blocks, much like our calendar has months, years, decades and centuries.

   The basic unit is a k’in - one day.
   A 20 day month is a winal.
   18 winal (360 days) is a tun - sometimes referred to as a short year.
   20 short years (tun) is a k’atun
   20 k’atun is a bak’tun

There are longer units too:

   Piktun == 20 Bak’tun (8,000 short years)
   Kalabtun  == 20 Piktun (160,000 short years)
   Kinchiltun  == 20 Kalabtun (3,200,000 short years)

For the most part, the Maya only used the blocks of time up to the bak’tun. One bak’tun is around 394 years, much more than a human life span, so that was all they usually needed to describe dates in this era, or this world. It is worth noting, the two calendars working together allow much more accurate and reliable notation for dates than is available in many other calendar systems; mostly due to the pragmatic choice to make the calendar simply track days, rather than trying to make it align with seasons and/or try to conflate it with the notion of time.

Mayan Date correlations

There is some controversy over finding a correlation point between the Gregorian and Mayan calendars. The Gregorian calendar is full of jumps and skips to keep the calendar aligned with the seasons so is much more difficult to work with. The most commonly used correlation factor is The GMT: 584283. Julian 584283 is a day count corresponding Mon, Aug 11, 3114 BCE in the Gregorian calendar, and the final day in the last Mayan long count cycle: 13.0.0.0.0 which is referred to as "the day of creation" in the Mayan calendar. There is nothing in known Mayan writing or history that suggests that a long count "cycle" resets every 13 bak’tun. Judging by their other practices, it would make much more sense for it to reset at 20, if at all.

The reason there was much interest at all, outside historical scholars, in the Mayan calendar is that the long count recently (relatively speaking) rolled over to 13.0.0.0.0 (the same as the historic day of creation Long Count date) on Fri, Dec 21, 2012 (using the most common GMT correlation factor), prompting conspiracy theorists to predict a cataclysmic "end-of-the-world" scenario.

Excerpts taken from, and recommended reading:


The Task:

Write a reusable routine that takes a Gregorian date and returns the equivalent date in Mayan in the Calendar Round and the Long Count. At a minimum, use the GMT correlation. If desired, support other correlations.

Using the GMT correlation, the following Gregorian and Mayan dates are equivalent:

  Dec 21, 2012 (Gregorian)
  4 Ajaw 3 K’ank’in G9 (Calendar round)
  13.0.0.0.0 (Long count)

Support looking up dates for at least 50 years before and after the Mayan Long Count 13 bak’tun rollover: Dec 21, 2012. (Will require taking into account Gregorian leap days.)

Show the output here, on this page, for at least the following dates:

(Note that these are in ISO-8601 format: YYYY-MM-DD. There is no requirement to use ISO-8601 format in your program, but if you differ, make a note of the expected format.)

   2004-06-19
   2012-12-18
   2012-12-21
   2019-01-19
   2019-03-27
   2020-02-29
   2020-03-01

Fortran

<lang Fortran>

     PROGRAM MAYA_DRIVER
     IMPLICIT NONE

! ! Local variables !

     CHARACTER(80)  ::  haab_carry
     CHARACTER(80)  ::  long_carry
     CHARACTER(80)  ::  nightlord
     CHARACTER(80)  ::  tzolkin_carry
     INTEGER,DIMENSION(8) :: DAY, MONTH, YEAR
     INTEGER :: INDEX
     DATA YEAR /2071,2004,2012,2012,2019,2019,2020,2020/
     DATA MONTH /5,6,12,12,1,3,2,3/
     DATA DAY /16,19,18,21,19,27,29,01/

! 2071-05-16 ! 2004-06-19 ! 2012-12-18 ! 2012-12-21 ! 2019-01-19 ! 2019-03-27 ! 2020-02-29 ! 2020-03-01

     DO INDEX = 1,8

!

         CALL MAYA_TIME(day(INDEX) , month(INDEX) , year(INDEX) , long_carry , haab_carry , tzolkin_carry ,       &
                      & nightlord)
         WRITE(6,20)day(INDEX),month(INDEX),year(INDEX),TRIM(tzolkin_carry),TRIM(haab_carry),TRIM(long_carry),TRIM(nightlord)

20 FORMAT(1X,I0,'-',I0,'-',I0,T12,A,T24,A,T38,A,T58,A)

     END DO
     STOP
     END PROGRAM MAYA_DRIVER

! ! SUBROUTINE MAYA_TIME

   subroutine maya_time(day,month,year, long_carry,haab_carry, tzolkin_carry,nightlord)
   implicit none
   integer(kind=4), parameter :: startdate = 584283    ! Start of the Mayan Calendar in Julian days
   integer(kind=4), parameter :: kin = 1
   integer(kind=4), parameter :: winal = 20*kin
   integer(kind=4), parameter :: tun = winal*18
   integer(kind=4), parameter :: katun = tun*20
   integer(kind=4), parameter :: baktun = katun*20
   integer(kind=4), parameter :: piktun = baktun*20    
   integer(kind=4), parameter :: longcount = baktun*20

!

   character(len=8), dimension(20) ,parameter :: tzolkin = &
                                            ["Imix'   ", "Ik´     ", "Ak´bal  ", "K´an    ", "Chikchan", "Kimi    ", &
                                             "Manik´  ", "Lamat   ", "Muluk   ", "Ok      ", "Chuwen  ", "Eb      ", &
                                             "Ben     ", "Hix     ", "Men     ", "K´ib´   ", "Kaban   ", "Etz´nab´", &
                                             "Kawak   ", "Ajaw    "]
   character(len=8), dimension(19) ,parameter :: haab = &
                                            ["Pop     ", "Wo´     ", "Sip     ", "Sotz´   ", "Sek     ", "Xul     ", &
                                             "Yaxk´in ", "Mol     ", "Ch´en   ", "Yax     ", "Sak´    ", "Keh     ", &
                                             "Mak     ", "K´ank´in", "Muwan   ", "Pax     ", "K´ayab  ", "Kumk´u  ", &
                                             "Wayeb´  "]
   character(len=20), dimension(9) ,parameter :: night_lords = &
                                            ["(G1) Xiuhtecuhtli   ", & ! ("Turquoise/Year/Fire Lord")
                                             "(G2) Tezcatlipoca   ", & ! ("Smoking Mirror")
                                             "(G3) Piltzintecuhtli", & ! ("Prince Lord")
                                             "(G4) Centeotl       ", & ! ("Maize God")
                                             "(G5) Mictlantecuhtli", & ! ("Underworld Lord")
                                             "(G6) Chalchiuhtlicue", & ! ("Jade Is Her Skirt")
                                             "(G7) Tlazolteotl    ", & ! ("Filth God[dess]")
                                             "(G8) Tepeyollotl    ", & ! ("Mountain Heart")
                                             "(G9) Tlaloc         "  ] ! (Rain God)
   integer(kind=4) :: day,month,year
   intent(in)      :: day,month,year

!

   integer(kind=4) :: j,l, numdays, keptdays
   integer(kind=4) :: kin_no, winal_no, tun_no, katun_no, baktun_no, longcount_no
   character(*) :: haab_carry, nightlord, tzolkin_carry, long_carry
   intent(inout) :: haab_carry, nightlord, tzolkin_carry, long_carry
   integer :: mo,da

!

   keptdays = julday(day,month,year)           ! Get the Julian date for selected date
   numdays = keptdays                          ! Keep for calcs later

! Adjust from the beginning

   numdays = numdays-startdate                 ! Adjust the number of days from start of Mayan Calendar
   if (numdays .ge. longcount)then             ! We check if we have passed a longcount and need to adjust for a new start
       longcount_no = numdays/longcount
       print*, ' We have more than one longcount ',longcount_no
   endif

! ! Calculate the longdate

   baktun_no = numdays/baktun
   numdays = numdays - (baktun_no*baktun)      ! Decrement days down by the number of baktuns    
   katun_no = numdays/katun                    ! Get number of katuns
   numdays = numdays - (katun_no*katun)
   tun_no = numdays/tun
   numdays = numdays-(tun_no*tun)
   winal_no = numdays/winal
   numdays = numdays-(winal_no*winal)
   kin_no = numdays                                ! What is left is simply the days
   long_carry = ' '                                ! blank it out
   write(long_carry,'(4(i2.2,"."),I2.2)') baktun_no,katun_no,tun_no,winal_no,kin_no

! ! OK. Now the longcount is done, let's calculate Tzolk´in, Haab´ & Nightlord (the calendar round) !

   haab_carry = " "
   L = mod((keptdays+65),365)
   mo = (L/20)+1
   da = mod(l,20)
   if(da.ne.0)then
       write(haab_carry,'(i2,1x,a)') da,haab(mo)
   else
       write(haab_carry,'(a,1x,a)') 'Chum',haab(mo)
   endif

! ! Ok, Now let's calculate the Tzolk´in ! The calendar starts on the 4 Ahu

   tzolkin_carry = " "                     ! Total blank the carrier
   mo = mod((keptdays+16),20) + 1
   da = mod((keptdays+5),13) + 1
   write(tzolkin_carry,'(i2,1x,a)') da,tzolkin(mo)

! ! Now let's have a look at the lords of the night ! There are 9 lords of the night, let's assume that they start on the first day of the year !

   numdays = keptdays -startdate           ! Elapsed Julian days since start of calendar
   J = mod(numdays,9)                      ! Number of days into this cycle
   if (j.eq.0) j = 9
   nightlord = night_lords(j)
   RETURN
   contains

!

   FUNCTION JULDAY( Id , Mm,  Iyyy)
     IMPLICIT NONE

! ! PARAMETER definitions !

     INTEGER , PARAMETER  ::  IGREG = 15 + 31*(10 + 12*1582)

! ! Dummy arguments !

     INTEGER  ::  Id , Iyyy , Mm
     INTEGER  ::  JULDAY
     INTENT (IN) Id , Iyyy , Mm

! ! Local variables !

     INTEGER  ::  ja , jm , jy

!

     jy = Iyyy
     IF(jy == 0)STOP 'julday: there is no year zero'
     IF(jy < 0)jy = jy + 1
     IF(Mm > 2)THEN
        jm = Mm + 1
     ELSE
        jy = jy - 1
        jm = Mm + 13
     END IF
     JULDAY = 365*jy + INT(0.25D0*jy + 2000.D0) + INT(30.6001D0*jm) + Id + 1718995
     IF(Id + 31*(Mm + 12*Iyyy) >= IGREG)THEN
        ja = INT(0.01D0*jy)
        JULDAY = JULDAY + 2 - ja + INT(0.25D0*ja)
     END IF
     RETURN
         END FUNCTION JULDAY
   END SUBROUTINE maya_time

</lang>

Output:
 16-5-2071  1 Ok       18 Sip        13.02.19.04.10      (G9) Tlaloc
 19-6-2004  4 Ben      16 Sotz´      12.19.11.06.13      (G7) Tlazolteotl
 18-12-2012 1 Kaban    Chum K´ank´in 12.19.19.17.17      (G6) Chalchiuhtlicue
 21-12-2012 4 Ajaw     3 K´ank´in    13.00.00.00.00      (G9) Tlaloc
 19-1-2019  1 Ajaw     13 Muwan      13.00.06.03.00      (G6) Chalchiuhtlicue
 27-3-2019  3 Manik´   Chum Wayeb´   13.00.06.06.07      (G1) Xiuhtecuhtli
 29-2-2020  4 Kimi     14 K´ayab     13.00.07.05.06      (G7) Tlazolteotl
 1-3-2020   5 Manik´   15 K´ayab     13.00.07.05.07      (G8) Tepeyollotl

Go

<lang go>package main

import (

   "fmt"
   "strconv"
   "strings"
   "time"

)

var sacred = strings.Fields("Imix’ Ik’ Ak’bal K’an Chikchan Kimi Manik’ Lamat Muluk Ok Chuwen Eb Ben Hix Men K’ib’ Kaban Etz’nab’ Kawak Ajaw")

var civil = strings.Fields("Pop Wo’ Sip Sotz’ Sek Xul Yaxk’in Mol Ch’en Yax Sak’ Keh Mak K’ank’in Muwan’ Pax K’ayab Kumk’u Wayeb’")

var (

   date1 = time.Date(2012, time.December, 21, 0, 0, 0, 0, time.UTC)
   date2 = time.Date(2019, time.April, 2, 0, 0, 0, 0, time.UTC)

)

func tzolkin(date time.Time) (int, string) {

   diff := int(date.Sub(date1).Hours()) / 24
   rem := diff % 13
   if rem < 0 {
       rem = 13 + rem
   }
   var num int
   if rem <= 9 {
       num = rem + 4
   } else {
       num = rem - 9
   }
   rem = diff % 20
   if rem <= 0 {
       rem = 20 + rem
   }
   return num, sacred[rem-1]

}

func haab(date time.Time) (string, string) {

   diff := int(date.Sub(date2).Hours()) / 24
   rem := diff % 365
   if rem < 0 {
       rem = 365 + rem
   }
   month := civil[(rem+1)/20]
   last := 20
   if month == "Wayeb’" {
       last = 5
   }
   d := rem%20 + 1
   if d < last {
       return strconv.Itoa(d), month
   }
   return "Chum", month

}

func longCount(date time.Time) string {

   diff := int(date.Sub(date1).Hours()) / 24
   diff += 13 * 400 * 360
   baktun := diff / (400 * 360)
   diff %= 400 * 360
   katun := diff / (20 * 360)
   diff %= 20 * 360
   tun := diff / 360
   diff %= 360
   winal := diff / 20
   kin := diff % 20
   return fmt.Sprintf("%d.%d.%d.%d.%d", baktun, katun, tun, winal, kin)    

}

func lord(date time.Time) string {

   diff := int(date.Sub(date1).Hours()) / 24
   rem := diff % 9
   if rem <= 0 {
       rem = 9 + rem
   }
   return fmt.Sprintf("G%d", rem)

}

func main() {

   const shortForm = "2006-01-02"
   dates := []string{
       "2004-06-19",
       "2012-12-18",
       "2012-12-21",
       "2019-01-19",
       "2019-03-27",
       "2020-02-29",
       "2020-03-01",
       "2071-05-16",
   }
   fmt.Println(" Gregorian   Tzolk’in        Haab’              Long           Lord of")
   fmt.Println("   Date       # Name       Day Month            Count         the Night")
   fmt.Println("----------   --------    -------------        --------------  ---------")
   for _, dt := range dates {
       date, _ := time.Parse(shortForm, dt)
       n, s := tzolkin(date)
       d, m := haab(date)
       lc := longCount(date)
       l := lord(date)
       fmt.Printf("%s   %2d %-8s %4s %-9s       %-14s     %s\n", dt, n, s, d, m, lc, l)
   }

}</lang>

Output:
 Gregorian   Tzolk’in        Haab’              Long           Lord of
   Date       # Name       Day Month            Count         the Night
----------   --------    -------------        --------------  ---------
2004-06-19    4 Ben        16 Sotz’           12.19.11.6.13      G7
2012-12-18    1 Kaban    Chum K’ank’in        12.19.19.17.17     G6
2012-12-21    4 Ajaw        3 K’ank’in        13.0.0.0.0         G9
2019-01-19    1 Ajaw       13 Muwan’          13.0.6.3.0         G6
2019-03-27    3 Manik’   Chum Wayeb’          13.0.6.6.7         G1
2020-02-29    4 Kimi       14 K’ayab          13.0.7.5.6         G7
2020-03-01    5 Manik’     15 K’ayab          13.0.7.5.7         G8
2071-05-16    1 Ok         18 Sip             13.2.19.4.10       G9

J

Implementation: <lang J>require 'types/datetime'

NB. 1794214= (0 20 18 20 20#.13 0 0 0 0)-todayno 2012 12 21 longcount=: Template:Rplc&' .'":0 20 18 20 20

tsolkin=: (cut {{)n

  Imix’   Ik’     Ak’bal    K’an    Chikchan
  Kimi    Manik’  Lamat     Muluk   Ok
  Chuwen  Eb      Ben       Hix     Men
  K’ib’   Kaban   Etz’nab’  Kawak   Ajaw

}}-.LF)Template:(":1+13

haab=:(cut {{)n

  Pop      Wo’       Sip     Sotz’   Sek      Xul
  Yaxk’in  Mol       Ch’en   Yax     Sak’     Keh
  Mak      K’ank’in  Muwan   Pax     K’ayab   Kumk’u
  Wayeb’ 

}}-.LF)Template:'M D'=.0 20

round=: [:;:inv tsolkin;haab;'G',&":1+9|]

gmt=: >@(fmtDate;round;longcount)@todayno</lang>

Task examples: <lang J> gmt 2004 6 19 June 19, 2004 4 Ben 16 Sotz’ G7 12.19.10.4.13

  gmt 2012 12 18

December 18, 2012 1 Kaban Chum Mak G6 12.19.17.19.17

  gmt 2012 12 21

December 21, 2012 4 Ajaw 3 K’ank’in G9 13.0.0.0.0

  gmt 2019 1 19

January 19, 2019 1 Ajaw 13 Muwan G6 13.0.5.11.0

  gmt 2019 3 27

March 27, 2019 3 Manik’ Chum Kumk’u G1 13.0.5.14.7

  gmt 2019 2 29

March 1, 2019 3 Imix’ 14 K’ayab G2 13.0.5.13.1

  gmt 2019 3 1

March 1, 2019 3 Imix’ 14 K’ayab G2 13.0.5.13.1</lang>

Julia

Translation of: Go

<lang julia>using Dates

const Tzolk´in = [ "Imix´", "Ik´", "Ak´bal", "K´an", "Chikchan", "Kimi", "Manik´", "Lamat", "Muluk", "Ok", "Chuwen", "Eb", "Ben", "Hix", "Men", "K´ib´", "Kaban", "Etz´nab´", "Kawak", "Ajaw" ] const Haab´ = [ "Pop", "Wo´", "Sip", "Sotz´", "Sek", "Xul", "Yaxk´in", "Mol", "Ch´en", "Yax", "Sak´", "Keh", "Mak", "K´ank´in", "Muwan", "Pax", "K´ayab", "Kumk´u", "Wayeb´" ] const creationTzolk´in = Date(2012, 12, 21) const zeroHaab´ = Date(2019, 4, 2) daysperMayanmonth(month) = (month == "Wayeb´" ? 5 : 20)

function tzolkin(gregorian::Date)

   deltadays = (gregorian - creationTzolk´in).value
   rem = mod1(deltadays, 13)
   return string(rem <= 9 ? rem + 4 : rem - 9) * " " * Tzolk´in[mod1(deltadays, 20)]

end

function haab(gregorian::Date)

   rem = mod1((gregorian - zeroHaab´).value, 365)
   month = Haab´[(rem + 21) ÷ 20]
   dayofmonth = rem % 20 + 1
   return dayofmonth < daysperMayanmonth(month) ? "$dayofmonth $month" : "Chum $month"

end

function tolongdate(gregorian::Date)

   delta = (gregorian - creationTzolk´in).value + 13 * 360 * 400
   baktun = delta ÷ (360 * 400)
   delta %= (400 * 360)
   katun = delta ÷ (20 * 360)
   delta %= (20 * 360)
   tun = delta ÷ 360
   delta %= 360
   winal, kin = divrem(delta, 20)
   return mapreduce(x -> lpad(x, 3), *, [baktun, katun, tun, winal, kin])

end

nightlord(gregorian::Date) = "G$(mod1((gregorian - creationTzolk´in).value, 9))"

testdates = [ Date(1963, 11, 21), Date(2004, 06, 19), Date(2012, 12, 18), Date(2012, 12, 21), Date(2019, 01, 19), Date(2019, 03, 27), Date(2020, 02, 29), Date(2020, 03, 01), Date(2071, 5, 16), Date(2020, 2, 2) ]

println("Gregorian Long Count Tzolk´in Haab´ Nightlord") println("-----------------------------------------------------------------") for date in testdates

   println(rpad(date,14), rpad(tolongdate(date), 18), rpad(tzolkin(date), 10),
       rpad(haab(date), 15), nightlord(date))

end

</lang>

Output:
Gregorian      Long Count       Tzolk´in  Haab´       Nightlord
-----------------------------------------------------------------
1963-11-21     12 17 10  3 12   3 Eb      Chum Keh       G9
2004-06-19     12 19 11  6 13   4 Ben     16 Sotz´       G7
2012-12-18     12 19 19 17 17   1 Kaban   Chum K´ank´in  G6
2012-12-21     13  0  0  0  0   4 Ajaw    3 K´ank´in     G9
2019-01-19     13  0  6  3  0   1 Ajaw    13 Muwan       G6
2019-03-27     13  0  6  6  7   3 Manik´  Chum Wayeb´    G1
2020-02-29     13  0  7  5  6   4 Kimi    14 K´ayab      G7
2020-03-01     13  0  7  5  7   5 Manik´  15 K´ayab      G8
2071-05-16     13  2 19  4 10   1 Ok      18 Sip         G9
2020-02-02     13  0  7  3 19   3 Kawak   7 Pax          G7

Mathematica/Wolfram Language

<lang Mathematica>sacred = {"Imix\[CloseCurlyQuote]", "Ik\[CloseCurlyQuote]",

  "Ak\[CloseCurlyQuote]bal", "K\[CloseCurlyQuote]an", "Chikchan", 
  "Kimi", "Manik\[CloseCurlyQuote]", "Lamat", "Muluk", "Ok", 
  "Chuwen", "Eb", "Ben", "Hix", "Men", 
  "K\[CloseCurlyQuote]ib\[CloseCurlyQuote]", "Kaban", 
  "Etz\[CloseCurlyQuote]nab\[CloseCurlyQuote]", "Kawak", "Ajaw"};

civil = {"Pop", "Wo\[CloseCurlyQuote]", "Sip",

  "Sotz\[CloseCurlyQuote]", "Sek", "Xul", "Yaxk\[CloseCurlyQuote]in",
   "Mol", "Ch\[CloseCurlyQuote]en", "Yax", "Sak\[CloseCurlyQuote]", 
  "Keh", "Mak", "K\[CloseCurlyQuote]ank\[CloseCurlyQuote]in", 
  "Muwan\[CloseCurlyQuote]", "Pax", "K\[CloseCurlyQuote]ayab", 
  "Kumk\[CloseCurlyQuote]u", "Wayeb\[CloseCurlyQuote]"};

date1 = {2012, 12, 21, 0, 0, 0}; date2 = {2019, 4, 2, 0, 0, 0};

ClearAll[Tzolkin] Tzolkin[date_] := Module[{diff, rem, num},

 diff = QuantityMagnitude[DateDifference[date1, date], "Days"];
 rem = Mod[diff, 13];
 If[rem <= 9,
  num = rem + 4
  ,
  num = rem - 9
  ];
 rem = Mod[diff, 20, 1];
 ToString[num] <> " " <> sacredrem
 ]

ClearAll[Haab] Haab[date_] := Module[{diff, rem, month, last, d},

 diff = QuantityMagnitude[DateDifference[date2, date], "Days"];
 rem = Mod[diff, 365];
 month = civil[[Floor[(rem + 1)/20] + 1]];
 last = 20;
 If[month == Last[civil],
  last = 5
  ];
 d = Mod[rem, 20] + 1;
 If[d < last,
  ToString[d] <> " " <> month
  ,
  "Chum " <> month
  ]
 ]

ClearAll[LongCount] LongCount[date_] := Module[{diff, baktun, katun, tun, winal, kin},

 diff = QuantityMagnitude[DateDifference[date1, date], "Days"];
 diff += 13 400 360;
 {baktun, diff} = QuotientRemainder[diff, 400 360];
 {katun, diff} = QuotientRemainder[diff, 20 360];
 {tun, diff} = QuotientRemainder[diff, 360];
 {winal, kin} = QuotientRemainder[diff, 20];
 StringRiffle[ToString /@ {baktun, katun, tun, winal, kin}, "."]
 ]

ClearAll[LordOfTheNight] LordOfTheNight[date_] := Module[{diff, rem},

 diff = QuantityMagnitude[DateDifference[date1, date], "Days"];
 rem = Mod[diff, 9, 1];
 "G" <> ToString[rem]
 ]

data = {{2004, 06, 19}, {2012, 12, 18}, {2012, 12, 21}, {2019, 01,

   19}, {2019, 03, 27}, {2020, 02, 29}, {2020, 03, 01}, {2071, 05, 
   16}};

tzolkindata = Tzolkin /@ data; haabdata = Haab /@ data; longcountdata = LongCount /@ data; lotndata = LordOfTheNight /@ data; {DateObject /@ data, tzolkindata, haabdata, longcountdata, lotndata} // Transpose // Grid</lang>

Output:
Sat 19 Jun 2004	4 Ben		16 Sotz'	12.19.11.6.13	G7
Tue 18 Dec 2012	1 Kaban		Chum K'ank'in	12.19.19.17.17	G6
Fri 21 Dec 2012	4 Ajaw		3 K'ank'in	13.0.0.0.0	G9
Sat 19 Jan 2019	1 Ajaw		13 Muwan'	13.0.6.3.0	G6
Wed 27 Mar 2019	3 Manik'	Chum Wayeb'	13.0.6.6.7	G1
Sat 29 Feb 2020	4 Kimi		14 K'ayab	13.0.7.5.6	G7
Sun 1 Mar 2020	5 Manik'	15 K'ayab	13.0.7.5.7	G8
Sat 16 May 2071	1 Ok		18 Sip		13.2.19.4.10	G9

Nim

Translation of: Julia

<lang Nim>import math, strformat, times

const

 Tzolk´in = ["Imix´", "Ik´", "Ak´bal", "K´an", "Chikchan", "Kimi", "Manik´", "Lamat", "Muluk", "Ok",
             "Chuwen", "Eb", "Ben", "Hix", "Men", "K´ib´", "Kaban", "Etz´nab´", "Kawak", "Ajaw"]
 Haab´ = ["Pop", "Wo´", "Sip", "Sotz´", "Sek", "Xul", "Yaxk´in", "Mol", "Ch´en", "Yax",
          "Sak´", "Keh", "Mak", "K´ank´in", "Muwan", "Pax", "K´ayab", "Kumk´u", "Wayeb´"]

let

 creationTzolk´in = initDateTime(21, mDec, 2012, 0, 0, 0, utc())
 zeroHaab´ = initDateTime(2, mApr, 2019, 0, 0, 0, utc())

func daysPerMayanMonth(month: string): int =

 if month == "Wayeb´": 5 else: 20

proc tzolkin(gregorian: DateTime): string =

 let deltaDays = (gregorian - creationTzolk´in).inDays
 let rem = floorMod(deltaDays, 13)
 result = $(if rem <= 9: rem + 4 else: rem - 9) & ' ' & Tzolk´in[floorMod(deltaDays - 1, 20)]

proc haab(gregorian: DateTime): string =

 let rem = floorMod((gregorian - zeroHaab´).inDays, 365)
 let month = Haab´[(rem + 1) div 20]
 let dayOfMonth = rem mod 20 + 1
 result = if dayOfMonth < daysPerMayanMonth(month): &"{dayOfMonth} {month}" else: &"Chum {month}"

proc toLongDate(gregorian: DateTime): string =

 var delta = (gregorian - creationTzolk´in).inDays + 13 * 360 * 400
 var baktun = delta div (360 * 400)
 delta = delta mod (400 * 360)
 let katun = delta div (20 * 360)
 delta = delta mod (20 * 360)
 let tun = delta div 360
 delta = delta mod 360
 let winal = delta div 20
 let kin = delta mod 20
 result = &"{baktun:2} {katun:2} {tun:2} {winal:2} {kin:2}"

proc nightLord(gregorian: DateTime): string =

 var rem = (gregorian - creationTzolk´in).inDays mod 9
 if rem <= 0: rem += 9
 result = 'G' & $rem


when isMainModule:

 let testDates = [initDateTime(21, mNov, 1963, 0, 0, 0, utc()),
                  initDateTime(19, mJun, 2004, 0, 0, 0, utc()),
                  initDateTime(18, mDec, 2012, 0, 0, 0, utc()),
                  initDateTime(21, mDec, 2012, 0, 0, 0, utc()),
                  initDateTime(19, mJan, 2019, 0, 0, 0, utc()),
                  initDateTime(27, mMar, 2019, 0, 0, 0, utc()),
                  initDateTime(29, mFeb, 2020, 0, 0, 0, utc()),
                  initDateTime(01, mMar, 2020, 0, 0, 0, utc()),
                  initDateTime(16, mMay, 2071, 0, 0, 0, utc()),
                  initDateTime(02, mfeb, 2020, 0, 0, 0, utc())]

echo "Gregorian Long Count Tzolk´in Haab´ Nightlord" echo "———————————————————————————————————————————————————————————————" for date in testDates:

 let dateStr = date.format("YYYY-MM-dd")
 echo &"{dateStr:14} {date.toLongDate:16} {tzolkin(date):9} {haab(date):14} {nightLord(date)}"</lang>
Output:
Gregorian      Long Count       Tzolk´in  Haab´       Nightlord
———————————————————————————————————————————————————————————————
1963-11-21     12 17 10  3 12   3 Eb      Chum Keh       G9
2004-06-19     12 19 11  6 13   4 Ben     16 Sotz´       G7
2012-12-18     12 19 19 17 17   1 Kaban   Chum K´ank´in  G6
2012-12-21     13  0  0  0  0   4 Ajaw    3 K´ank´in     G9
2019-01-19     13  0  6  3  0   1 Ajaw    13 Muwan       G6
2019-03-27     13  0  6  6  7   3 Manik´  Chum Wayeb´    G1
2020-02-29     13  0  7  5  6   4 Kimi    14 K´ayab      G7
2020-03-01     13  0  7  5  7   5 Manik´  15 K´ayab      G8
2071-05-16     13  2 19  4 10   1 Ok      18 Sip         G9
2020-02-02     13  0  7  3 19   3 Kawak   7 Pax          G7

Perl

The module Math::BaseArith provides mixed-radix conversion via the encode routine (named as in APL).

Translation of: Raku

<lang perl>use strict; use warnings; use utf8; binmode STDOUT, ":utf8"; use Math::BaseArith; use Date::Calc 'Delta_Days';

my @sacred = qw<Imix’ Ik’ Ak’bal K’an Chikchan Kimi Manik’ Lamat Muluk Ok

             Chuwen Eb Ben Hix Men K’ib’ Kaban Etz’nab’ Kawak Ajaw>;

my @civil = qw<Pop Wo’ Sip Sotz’ Sek Xul Yaxk’in Mol Ch’en Yax Sak’ Keh

            Mak K’ank’in Muwan’ Pax K’ayab Kumk’u Wayeb’>;

my %correlation = (

   'gregorian' => '2012-12-21',
   'round'     => [3,19,263,8],
   'long'      => 1872000,

);

sub mayan_calendar_round {

   my $date = shift;
   tzolkin($date), haab($date);

}

sub offset {

   my $date = shift;
   Delta_Days( split('-', $correlation{'gregorian'}), split('-', $date) );

}

sub haab {

   my $date  = shift;
   my $index = ($correlation{'round'}[2] + offset $date) % 365;
   my ($day, $month);
   if ($index > 360) {
       $day = $index - 360;
       $month = $civil[18];
       if ($day == 5) {
           $day = 'Chum';
           $month = $civil[0];
       }
   } else {
       $day = $index % 20;
       $month = $civil[int $index / 20];
       if ($day == 0) {
           $day = 'Chum';
           $month = $civil[int (1 + $index) / 20];
       }
   }
   $day, $month

}

sub tzolkin {

   my $date   = shift;
   my $offset = offset $date;
   1 + ($offset + $correlation{'round'}[0]) % 13,
   $sacred[($offset + $correlation{'round'}[1]) % 20]

}

sub lord {

   my $date = shift;
   1 + ($correlation{'round'}[3] + offset $date) % 9

}

sub mayan_long_count {

   my $date = shift;
   my $days = $correlation{'long'} + offset $date;
   encode($days, [20,20,20,18,20]);

}

print <<'EOH';

Gregorian   Tzolk’in         Haab’             Long           Lord of
  Date       # Name       Day Month            Count         the Night

EOH

for my $date (<1961-10-06 2004-06-19 2012-12-18 2012-12-21 2019-01-19 2019-03-27 2020-02-29 2020-03-01 2071-05-16>) {

   printf "%10s   %2s %-9s %4s %-10s     %-14s     G%d\n",
     $date, mayan_calendar_round($date), join('.',mayan_long_count($date)), lord($date);

}</lang>

Output:
 Gregorian   Tzolk’in         Haab’             Long           Lord of
   Date       # Name       Day Month            Count         the Night
-----------------------------------------------------------------------

1961-10-06    7 K’ib’       14 Ch’en          12.17.8.0.16       G7
2004-06-19    4 Ben         16 Sotz’          12.19.11.6.13      G7
2012-12-18    1 Kaban     Chum K’ank’in       12.19.19.17.17     G6
2012-12-21    4 Ajaw         3 K’ank’in       13.0.0.0.0         G9
2019-01-19    1 Ajaw        13 Muwan’         13.0.6.3.0         G6
2019-03-27    3 Manik’    Chum Wayeb’         13.0.6.6.7         G1
2020-02-29    4 Kimi        14 K’ayab         13.0.7.5.6         G7
2020-03-01    5 Manik’      15 K’ayab         13.0.7.5.7         G8
2071-05-16    1 Ok          18 Sip            13.2.19.4.10       G9

Phix

Translation of: Go
with javascript_semantics
include timedate.e
 
sequence sacred = split("Imix' Ik' Ak'bal K'an Chikchan Kimi Manik' Lamat Muluk Ok Chuwen Eb Ben Hix Men K'ib' Kaban Etz'nab' Kawak Ajaw"),
         civil = split("Pop Wo' Sip Sotz' Sek Xul Yaxk'in Mol Ch'en Yax Sak' Keh Mak K'ank'in Muwan' Pax K'ayab Kumk'u Wayeb'"),
         date1 = parse_date_string("21/12/2012",{"DD/MM/YYYY"}),
         date2 = parse_date_string("2/4/2019",{"DD/MM/YYYY"})
 
function tzolkin(integer diff)
    integer rem = mod(diff,13)
    if rem<0 then rem += 13 end if
    integer num = iff(rem<=9?rem+4:rem-9)
    rem = mod(diff,20)
    if rem<=0 then rem += 20 end if
    return {num, sacred[rem]}
end function
 
function haab(integer diff)
    integer rem = mod(diff,365)
    if rem<0 then rem += 365 end if
    string month = civil[floor((rem+1)/20)+1]
    integer last = iff(month="Wayeb'"?5:20),
            d = mod(rem,20) + 1
    return {iff(d<last?sprintf("%d",d):"Chum"), month}
end function
 
function longCount(integer diff)
    diff += 13 * 400 * 360
    integer baktun := floor(diff/(400*360))
    diff = mod(diff,400*360)
    integer katun := floor(diff/(20*360))
    diff = mod(diff,20*360)
    integer tun = floor(diff/360)
    diff = mod(diff,360)
    integer winal = floor(diff/20),
            kin = mod(diff,20)
    return sprintf("%d.%d.%d.%d.%d", {baktun, katun, tun, winal, kin})  
end function
 
function lord(integer diff)
    integer rem = mod(diff,9)
    if rem<=0 then rem += 9 end if
    return sprintf("G%d", rem)
end function
 
constant dates = {"1961-10-06",
                  "1963-11-21",
                  "2004-06-19",
                  "2012-12-18",
                  "2012-12-21",
                  "2019-01-19",
                  "2019-03-27",
                  "2020-02-29",
                  "2020-03-01",
                  "2071-05-16",
                 },
         headers = """
 Gregorian   Tzolk'in        Haab'              Long           Lord of
   Date       # Name       Day Month            Count         the Night
----------   --------    -------------        --------------  ---------
"""
 
procedure main()
    printf(1,headers)
    for i=1 to length(dates) do
        string dt = dates[i]
        timedate td = parse_date_string(dt,{"YYYY-MM-DD"})
        integer diff1 = floor(timedate_diff(date1,td,DT_DAY) / (24*60*60)),
                diff2 = floor(timedate_diff(date2,td,DT_DAY) / (24*60*60))
        {integer n, string s} = tzolkin(diff1)
        string {d, m} = haab(diff2),
               lc := longCount(diff1),
               l := lord(diff1)
        printf(1,"%s   %2d %-8s %4s %-9s       %-14s     %s\n", {dt, n, s, d, m, lc, l})
    end for
end procedure
main()
Output:
 Gregorian   Tzolk'in        Haab'              Long           Lord of
   Date       # Name       Day Month            Count         the Night
----------   --------    -------------        --------------  ---------
1961-10-06    7 K'ib'      14 Ch'en           12.17.8.0.16       G7
1963-11-21    3 Eb       Chum Keh             12.17.10.3.12      G9
2004-06-19    4 Ben        16 Sotz'           12.19.11.6.13      G7
2012-12-18    1 Kaban    Chum K'ank'in        12.19.19.17.17     G6
2012-12-21    4 Ajaw        3 K'ank'in        13.0.0.0.0         G9
2019-01-19    1 Ajaw       13 Muwan'          13.0.6.3.0         G6
2019-03-27    3 Manik'   Chum Wayeb'          13.0.6.6.7         G1
2020-02-29    4 Kimi       14 K'ayab          13.0.7.5.6         G7
2020-03-01    5 Manik'     15 K'ayab          13.0.7.5.7         G8
2071-05-16    1 Ok         18 Sip             13.2.19.4.10       G9

Raku

(formerly Perl 6)

Works with: Rakudo version 2018.12

<lang perl6>my @sacred = <Imix’ Ik’ Ak’bal K’an Chikchan Kimi Manik’ Lamat Muluk Ok

             Chuwen Eb Ben Hix Men K’ib’ Kaban Etz’nab’ Kawak Ajaw>;

my @civil = <Pop Wo’ Sip Sotz’ Sek Xul Yaxk’in Mol Ch’en Yax Sak’ Keh

            Mak K’ank’in Muwan’ Pax K’ayab Kumk’u Wayeb’>;

my %correlation = :GMT({

   :gregorian(Date.new('2012-12-21')),
   :round([3,19,263,8]),
   :long(1872000)

});

sub mayan-calendar-round ($date) { .&tzolkin, .&haab given $date }

sub offset ($date, $factor = 'GMT') { Date.new($date) - %correlation{$factor}<gregorian> }

sub haab ($date, $factor = 'GMT') {

   my $index = (%correlation{$factor}<round>[2] + offset $date) % 365;
   my ($day, $month);
   if $index > 360 {
       $day = $index - 360;
       $month = @civil[18];
       if $day == 5 {
           $day = 'Chum';
           $month = @civil[0];
       }
   } else {
       $day = $index % 20;
       $month = @civil[$index div 20];
       if $day == 0 {
           $day = 'Chum';
           $month = @civil[(1 + $index) div 20];
       }
   }
   $day, $month

}

sub tzolkin ($date, $factor = 'GMT') {

   my $offset = offset $date;
   1 + ($offset + %correlation{$factor}<round>[0]) % 13,
   @sacred[($offset + %correlation{$factor}<round>[1]) % 20]

}

sub lord ($date, $factor = 'GMT') {

   'G' ~ 1 + (%correlation{$factor}<round>[3] + offset $date) % 9

}

sub mayan-long-count ($date, $factor = 'GMT') {

   my $days = %correlation{$factor}<long> + offset $date;
   reverse $days.polymod(20,18,20,20);

}

  1. HEADER

say ' Gregorian Tzolk’in Haab’ Long Lord of '; say ' Date # Name Day Month Count the Night'; say '-----------------------------------------------------------------------';

  1. DATES

< 1963-11-21 2004-06-19 2012-12-18 2012-12-21 2019-01-19 2019-03-27 2020-02-29 2020-03-01 2071-05-16 >.map: -> $date {

   printf "%10s   %2s %-9s %4s %-10s     %-14s %6s\n", Date.new($date),
     flat mayan-calendar-round($date), mayan-long-count($date).join('.'), lord($date);

}</lang>

Output:
 Gregorian   Tzolk’in        Haab’              Long           Lord of 
   Date       # Name       Day Month            Count         the Night
-----------------------------------------------------------------------
1963-11-21    3 Eb        Chum Keh            12.17.10.3.12      G9
2004-06-19    4 Ben         16 Sotz’          12.19.11.6.13      G7
2012-12-18    1 Kaban     Chum K’ank’in       12.19.19.17.17     G6
2012-12-21    4 Ajaw         3 K’ank’in       13.0.0.0.0         G9
2019-01-19    1 Ajaw        13 Muwan’         13.0.6.3.0         G6
2019-03-27    3 Manik’    Chum Wayeb’         13.0.6.6.7         G1
2020-02-29    4 Kimi        14 K’ayab         13.0.7.5.6         G7
2020-03-01    5 Manik’      15 K’ayab         13.0.7.5.7         G8
2071-05-16    1 Ok          18 Sip            13.2.19.4.10       G9

Wren

Translation of: Go
Library: Wren-date
Library: Wren-fmt

<lang ecmascript>import "/date" for Date import "/fmt" for Fmt

var sacred = "Imix’ Ik’ Ak’bal K’an Chikchan Kimi Manik’ Lamat Muluk Ok Chuwen Eb Ben Hix Men K’ib’ Kaban Etz’nab’ Kawak Ajaw".split(" ")

var civil = "Pop Wo’ Sip Sotz’ Sek Xul Yaxk’in Mol Ch’en Yax Sak’ Keh Mak K’ank’in Muwan’ Pax K’ayab Kumk’u Wayeb’".split(" ")

var date1 = Date.new(2012, 12, 21) var date2 = Date.new(2019, 4, 2)

var tzolkin = Fn.new { |date|

   var diff = (date - date1).days
   var rem = diff % 13
   if (rem < 0) rem = 13 + rem
   var num = (rem <= 9) ? rem + 4 : rem - 9
   rem = diff % 20
   if (rem <= 0) rem = 20 + rem
   return [num, sacred[rem-1]]

}

var haab = Fn.new { |date|

   var diff = (date - date2).days
   var rem = diff % 365
   if (rem < 0) rem = 365 + rem
   var month = civil[((rem+1)/20).floor]
   var last = (month == "Wayeb'") ? 5 : 20
   var d = rem%20 + 1
   if (d < last) return [d.toString, month]
   return ["Chum", month]

}

var longCount = Fn.new { |date|

   var diff = (date - date1).days
   diff = diff + 13*400*360
   var baktun = (diff/(400*360)).floor
   diff = diff % (400*360)
   var katun = (diff/(20 * 360)).floor
   diff = diff % (20*360)
   var tun = (diff/360).floor
   diff = diff % 360
   var winal = (diff/20).floor
   var kin = diff % 20
   return Fmt.swrite("$d.$d.$d.$d.$d", baktun, katun, tun, winal, kin)

}

var lord = Fn.new { |date|

   var diff = (date - date1).days
   var rem = diff % 9
   if (rem <= 0) rem = 9 + rem
   return Fmt.swrite("G$d", rem)

}

var dates = [

   "1961-10-06",
   "1963-11-21",
   "2004-06-19",
   "2012-12-18",
   "2012-12-21",
   "2019-01-19",
   "2019-03-27",
   "2020-02-29",
   "2020-03-01",
   "2071-05-16"

] System.print(" Gregorian Tzolk’in Haab’ Long Lord of") System.print(" Date # Name Day Month Count the Night") System.print("---------- -------- ------------- -------------- ---------") Date.default = Date.isoDate for (dt in dates) {

   var date = Date.parse(dt)
   var ns = tzolkin.call(date)
   var n = ns[0]
   var s = ns[1]
   var dm = haab.call(date)
   var d = dm[0]
   var m = dm[1]
   var lc = longCount.call(date)
   var l = lord.call(date)
   Fmt.lprint("$s   $2d $-8s $4s $-9s       $-14s     $s", [dt, n, s, d, m, lc, l])

}</lang>

Output:
 Gregorian   Tzolk’in        Haab’              Long           Lord of
   Date       # Name       Day Month            Count         the Night
----------   --------    -------------        --------------  ---------
1961-10-06    7 K’ib’      14 Ch’en           12.17.8.0.16       G7
1963-11-21    3 Eb       Chum Keh             12.17.10.3.12      G9
2004-06-19    4 Ben        16 Sotz’           12.19.11.6.13      G7
2012-12-18    1 Kaban    Chum K’ank’in        12.19.19.17.17     G6
2012-12-21    4 Ajaw        3 K’ank’in        13.0.0.0.0         G9
2019-01-19    1 Ajaw       13 Muwan’          13.0.6.3.0         G6
2019-03-27    3 Manik’   Chum Wayeb’          13.0.6.6.7         G1
2020-02-29    4 Kimi       14 K’ayab          13.0.7.5.6         G7
2020-03-01    5 Manik’     15 K’ayab          13.0.7.5.7         G8
2071-05-16    1 Ok         18 Sip             13.2.19.4.10       G9

zkl

Translation of: Go

<lang zkl>var [const]

 sacred=T("Imix'","Ik'","Ak'bal","K'an","Chikchan","Kimi","Manik'","Lamat","Muluk","Ok",
          "Chuwen","Eb","Ben","Hix","Men","K'ib'","Kaban","Etz'nab'","Kawak","Ajaw"),
 civil=T("Pop","Wo'","Sip","Sotz'","Sek","Xul","Yaxk'in","Mol","Ch'en","Yax","Sak'","Keh",
         "Mak","K'ank'in","Muwan'","Pax","K'ayab","Kumk'u","Wayeb'"),
 Date=Time.Date,
 // correlation dates:
 Creation=T(2012, Date.December, 21),  // 13.0.0.0.0, Mayan day of creation
 OnePop=T(2019, Date.April, 2),	// 1 Pop in 2019

fcn haab(date){ // (y,m,d)-->("Chum"|Int,month name)

  diff:=Date.deltaDays(OnePop,date.xplode());	//--> signed int
  rem:=diff%365;
  if(rem<0) rem=365 + rem;
  month,last := civil[(rem+1)/20], 20;
  if(month==civil[-1]) last=5;
  d:=rem%20 + 1;
  if(d<last) return(d, month);
  return("Chum",month);

}

fcn tzolkin(date){ // (y,m,d)-->(Int,String)

  diff:=Date.deltaDays(Creation,date.xplode());	//--> signed int
  rem:=diff % 13;
  if(rem<0) rem=13 + rem;
  num:=( if(rem<=9) rem + 4 else rem - 9 );
  rem=diff % 20;
  if(rem<=0) rem=20 + rem;
  return(num, sacred[rem-1]);

}

fcn longCount(date){ // (y,m,d) --> (5 Ints)

  diff:=Date.deltaDays(Creation,date.xplode());	//--> signed int
  diff,baktun    := diff + 13*400*360, diff/(400*360);
  diff,katun     := diff % (400*360),  diff/(20*360);
  diff,tun       := diff % (20*360),   diff/360;
  diff,winal,kin := diff%360,          diff/20,       diff % 20;
  return(baktun, katun, tun, winal, kin)

}

fcn lord(date){ // (y,m,d) --> String

  diff:=Date.deltaDays(Creation,date.xplode());	//--> signed int
  rem:=diff % 9;
  if(rem<=0) rem=9 + rem;
  "G%d".fmt(rem)

}</lang> <lang zkl>println(" Gregorian Tzolk'in Haab' Long Lord of"); println(" Date # Name Day Month Count the Night"); println("---------- -------- ------------- -------------- ---------");

  1. <<<

" 1963-11-21 2004-06-19 2012-12-18 2012-12-21 2019-01-19 2019-03-27 2020-02-29 2020-03-01 2071-05-16 ".split()

  1. <<<

.pump(Void,fcn(date){

  ymd:=Date.parseDate(date);
  println("%10s   %2s %-9s %4s %-10s     %-14s %6s".fmt(date,
     tzolkin(ymd).xplode(), haab(ymd).xplode(),
     longCount(ymd).concat("."),
     lord(ymd)));

});</lang>

Output:
 Gregorian   Tzolk'in         Haab'             Long           Lord of
   Date       # Name       Day Month            Count         the Night
----------   --------    -------------        --------------  ---------
1963-11-21    3 Eb        Chum Keh            12.17.10.3.12      G9
2004-06-19    4 Ben         16 Sotz'          12.19.11.6.13      G7
2012-12-18    1 Kaban     Chum K'ank'in       12.19.19.17.17     G6
2012-12-21    4 Ajaw         3 K'ank'in       13.0.0.0.0         G9
2019-01-19    1 Ajaw        13 Muwan'         13.0.6.3.0         G6
2019-03-27    3 Manik'    Chum Wayeb'         13.0.6.6.7         G1
2020-02-29    4 Kimi        14 K'ayab         13.0.7.5.6         G7
2020-03-01    5 Manik'      15 K'ayab         13.0.7.5.7         G8
2071-05-16    1 Ok          18 Sip            13.2.19.4.10       G9