Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Python package and command line client to convert between Tzolk’in and Gregorian dates and calculate with Maya Tzolk’in dates. And a interactive Jupyter Notebook

License

Notifications You must be signed in to change notification settings

Release-Candidate/tzolkin-calendar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tzolkin-calendar - Converter for Maya Tzolk’in Dates

Warning

This repository has been moved to Codeberg: tzolkin-calendar

This program converts mayan Tzolk’in dates to Gregorian dates and vice versa. If you want to know more about the Maya calendar systems, see Links.

Information about the installation and usage you find at Installation and Usage

More detailed Documentation can be found at Read the Docs

Binder tzolkin-calendar Notebook MIT license badge Python version badge PIP version badge ReadTheDocs badge Code style: black more badges

Table of Contents

Links

Smithsonian Museo Nacional del Indígena Americano: Viviendo El Tiempo Maya

Website of the Smithsonian National Museum of the American Indian on Mayas Living Maya Time.

Online general Maya (not only Tzolk’in) calendar converter: Maya Converter of the Smithsonian NMAI

Convertidor Al Calendario Maya Smithsonian NMIA

Mayan Glyphs and Unicode: Roadmap to the SMP and the PDF Updated List of Characters for Mayan Codices

Installation and Usage

There are 3 Jupyter Notebooks online at Binder:

Interactive Tzolk’in converter: Binder tzolkin-calendar Notebook

Command line program: Binder

The usage of the module tzolkin-calendar in your code: Binder

Prerequisites

You need Python, at least version 3.8 to be able to use tzolkin-calendar. You can download it from python.org.

To install the package, you need pip, see Installing pip.

Installation

Install the package using pip on a shell or command prompt:

python -m pip install tzolkin-calendar

More information about using pip you get at pip Quickstart

Usage

Using the Command-Line Client

There is an online interactive Jupyter version: Binder

We start the command line client of tzolkin-calendar using python -m: beware of the underscore (_)

% python -m tzolkin_calendar
    Gregorian "24.03.2021" is "3 Men" as Tzolk’in

As default, if no argument is given, the Tzolk’in date of the current day ('today' ins the 24th of March, 2021) is printed.

To get the version of tzolkin_calendar, use the argument --version

% python -m tzolkin_calendar --version
    tzolkin-calendar 0.9.3

The argument --help displays a short usage text, we go through all options in the following parts.

% python -m tzolkin_calendar --help
    usage: python -m tzolkin_calendar [-h] [--version] [-l LIST_LENGTH]
                                      [-s START_DATE] [-y]
                                      [DATE ...]
    
    A Tzolk’in date converter and calculator.
    
    Examples:
    
    To get the Tzolk’in date of today:
    
     python -m tzolkin_calendar
    
    To get the next and last gregorian dates with a Tzolk’in date of '8 Chuwen' you can use either:
    
     python -m tzolkin_calendar 8 Chuwen
     python -m tzolkin_calendar 8/Chuwen
     python -m tzolkin_calendar 8.Chuwen
     python -m tzolkin_calendar 8-Chuwen
     python -m tzolkin_calendar 8 11
     python -m tzolkin_calendar 8/11
     python -m tzolkin_calendar 8.11
     python -m tzolkin_calendar 8-11
    
    To get the Tzolk’in date of the 16th april 2016, use one of these date formats:
    
        python -m tzolkin_calendar 16.04.2016
        python -m tzolkin_calendar 16-04-2016
        python -m tzolkin_calendar 16 04 2016
        python -m tzolkin_calendar 2016.04.16
        python -m tzolkin_calendar 2016-04-16
        python -m tzolkin_calendar 2016/04/16
        python -m tzolkin_calendar 2016 04 16
        python -m tzolkin_calendar 04/16/2016
    
    positional arguments:
      DATE                  The date to parse and convert. Either a Tzolk’in date or a gregorian date can be given. The default is the date of today.
    
    optional arguments:
      -h, --help            show this help message and exit
      --version             show program's version number and exit
      -l LIST_LENGTH, --list LIST_LENGTH
                            Display a list of dates with the given Tzolk’in date instead of a single one. The length of the list is LIST_LENGTH.
      -s START_DATE, --start START_DATE
                            The start date to begin the search for the dates with the same Tzolk’in date. The same formatting rules apply as for the main argument DATE.
      -y, --year            Print all dates of a Tzolk’in year.
    
    See website https://github.com/Release-Candidate/tzolkin_calendar for a detailed description.
Converting Gregorian Dates to Tzolk’in Dates

To get the Tzolk’in date of a Gregorian date use the Gregorian date as the main argument to tzolkin_calendar.

E.g. to get the Tzolk’in date of the 18th of May, 1974, which is "12 Akʼbʼal"

% python -m tzolkin_calendar 18.05.1974
    Gregorian "18.05.1974" is "12 Akʼbʼal" as Tzolk’in

Many date format conventions are supported, any of these work (and result in the 18th of May, 1974):
DD.MM.YYYY - 18.05.1974
DD-MM-YYYY - 18-05-1974
DD MM YYYY - 18 05 1974
YYYY.MM.DD - 1974.05.18
YYYY-MM-DD - 1974-05-18
YYYY/MM/DD - 1974/05/18
YYYY MM DD - 1974 05 18
MM/DD/YYYY - 05/18/1974

% python -m tzolkin_calendar 05/18/1974
    Gregorian "05/18/1974" is "12 Akʼbʼal" as Tzolk’in
Searching Tzolk’in Dates

To search for Gregorian Dates to a given Tzolk’in date, input the Tzolk’in date to search for.

As default the search is started today (the 24th of March, 2021). So, we search for "13 Lamat"

% python -m tzolkin_calendar 13 Lamat
    Tzolk’in date "13 Lamat" next date is "24.08.2021", last date has been "07.12.2020"

The next gregorian date with a Tzolk’in date of "12 Lamat" after today (the 24th of March 2021) is the 24th od August, 2021, the last gregorian date before today has been the 7th of December 2020.

We again can use many formats to pass as Tzolk’in dates:
DD NNNN - 13 Lamat
DD/NNNN - 13/Lamat
DD.NNNN - 13.Lamat
DD-NNNN - 13-Lamat

Instead of the name, we can also use the number of the day name (between 1 and 20), so instead of "Lamat" we could use the number 8. The valid formats are again (with or without leading zeroes).
DD NN - 13 8
DD/NN - 13/8
DD.NN - 13.8
DD-NN - 13-8

We can also search starting at other days than today, so lets start the search at the 18th of May 1974, this is the argument to --start

% python -m tzolkin_calendar 13 Lamat --start 18.05.1974
    Tzolk’in date "13 Lamat" next date is "31.08.1974", last date has been "14.12.1973"

Now the search returned the 31th of August, 1974 as the next and the 14th of December 1974 as the last Gregorian date with the same Tzolk’in date.

We can also search for more than one date in the future and the past, by using the argument --list, which is the number of Gregorian dates to return. Lets search for 5 Gregorian dates with a Tzolk’in date of "13 Lamat", starting at the 18th of May, 1974.

% python -m tzolkin_calendar 13 Lamat --start 18.05.1974 --list 5
    Tzolk’in date "13 Lamat"
     next dates are ['31.08.1974', '18.05.1975', '02.02.1976', '19.10.1976', '06.07.1977']
     last dates have been ['14.12.1973', '29.03.1973', '12.07.1972', '26.10.1971', '08.02.1971']

So we're getting 5 Gregorian dates after and before the 18th of May, 1974.

Without an --start argument, we start the search today (the 24th of March, 2021).

% python -m tzolkin_calendar 13 Lamat --list 5
    Tzolk’in date "13 Lamat"
     next dates are ['24.08.2021', '11.05.2022', '26.01.2023', '13.10.2023', '29.06.2024']
     last dates have been ['07.12.2020', '22.03.2020', '06.07.2019', '19.10.2018', '01.02.2018']

We can make the list as long as we want, but if the list would be too long, we ran out of the valid calendar days.

% python -m tzolkin_calendar 13 Lamat --list 10000
    Traceback (most recent call last):
      ...
      File "./tzolkin_calendar/calculate.py", line 432, in lastTzolkin
        return starting + day_diff_delta
    OverflowError: date value out of range
Print all Tzolk’in Dates in a Tzolk’in Year

To get a list of all 260 Tzolk’in dates in a Tzolk’in year, we use the argument --year:

% python -m tzolkin_calendar --year
     1 Imix 2 Ikʼ 3 Akʼbʼal 4 Kʼan 5 Chikchan 6 Kimi 7 Manikʼ 8 Lamat 9 Muluk 10 Ok 11 Chuwen 12 Ebʼ 13 Bʼen
     1 Ix
     ...
                                                                                                  13 Manikʼ
     1 Lamat 2 Muluk 3 Ok 4 Chuwen 5 Ebʼ 6 Bʼen 7 Ix 8 Men 9 Kʼibʼ 10 Kabʼan 11 Etzʼnabʼ 12 Kawak 13 Ajaw
    Gregorian "24.03.2021" is "3 Men" as Tzolk’in

Using the Jupyter Notebook

You can test it online at Binder. You need to restart the kernel first by going to the menu and selecting Kernel->Restart & Run All to get the interactive sliders and input fields.

You can get Information about Jupyter Notebooks at the official site

Install Jupyter Notebook and ipywidgets

python -m pip install notebook ipywidgets

If you want to be able to open the Jupyter notebook files directly, install nbopen.

python -m pip install nbopen

and add the extension to the list of extensions of your OS, so that you can double click the .ipynb files and Jupyter opens it.

On Linux:

python -m nbopen.install_xdg

On Windows:

python -m nbopen.install_win

For OS X, the installation is a bit more advanced, see nbopen

Download the Tzolk’in calendar notebook at Tzolk’in Calendar.ipynb

Open it in Jupyter Notebook and run all cells, by going to the menu and using Kernel->Restart & Run All .

You should now see something like:

Interactive view of Tzolk’in Calendar)

Using the Python Module in Your Programs

See the second Jupyter Notebook about how to use the tzolkin-calendar module: Binder

Import the Module

To use the Tzolk’in date package, import tzolkin_calender (with an underscore _).

A short check to see if it is working is to print the version of tzolkin-calendar, that's the constant tzolkin_calendar.VERSION.

# Import the package.
import tzolkin_calendar

# Check, if it is working.
tzolkin_calendar.VERSION
    '0.9.3'
The Tzolk’in Date Class Tzolkin

The Tzolk’in date class resides in the module tzolkin_calendar.tzolkin, and is named Tzolkin.

So, import that module:

# Import the module tzolkin that contains `Tzolkin`.
from tzolkin_calendar import tzolkin
Convert Gregorian Dates to Tzolk’in Dates

To get the Tzolk’in date of today, call the static method fromToday. This returns a Tzolkin instance holding the Tzolk’in date of today ('today' is the 24th of March, 2021, with a Tzolk’in date of '3 Men')

tzolkin.Tzolkin.fromToday()
    3 Men

You can generate a Tzolkin instance from any gregorian date using the datetime.date class or a date string.

So, first import the datetime module:

import datetime

And then use the 3 possibilities to set the Tzolk’in date from a gregorian date. Or, in other words, to convert a gregorian date to a Tzolk’in date.

  1. from a datetime.date instance using Tzolkin.fromDate. We use the method fromisoformat to set the gregorian date to the 24th of March 2021 with the date string '2021-03-24'. The Tzolk’in date of the 24th of March 2021 is '3 Men'.
gregorian_date = datetime.date.fromisoformat("2021-03-24")

tzolkin.Tzolkin.fromDate(gregorian_date)
    3 Men
  1. from an ISO date string using Tzolkin.fromIsoFormat. We set the Tzolk’in date to the 24th of March 2021 with the ISO date string '2021-03-24'. The Tzolk’in date of the 24th of March 2021 is '3 Men'.
tzolkin.Tzolkin.fromIsoFormat("2021-03-24")
    3 Men
  1. from an arbitrary date string using Tzolkin.fromDateString. We set the Tzolk’in date to the 24th of March 2021 with the date string '24=03*2021' and the format string fmt '%d=%m*%Y'. The Tzolk’in date of the 24th of March 2021 is '3 Men'.
tzolkin.Tzolkin.fromDateString("24=03*2021", fmt="%d=%m*%Y")
    3 Men
Set Tzolk’in Dates

You can set the Tzolkin instance to a Tzolk’in Date using it's constructor. The constructor takes the Tzolk’in day number (between 1 and 13 including 1 and 13) and either a Tzolk’in day name or the number of the Tzolk’in day name (between 1 and 20 , including 1 and 20).

To get a dictionary of Tzolk’in day names and numbers, look at tzolkin.day_names.

tzolkin.day_names
    {1: 'Imix', 2: 'Ikʼ', 3: 'Akʼbʼal', 4: 'Kʼan', 5: 'Chikchan', 6: 'Kimi',
     7: 'Manikʼ', 8: 'Lamat', 9: 'Muluk', 10: 'Ok', 11: 'Chuwen', 12: 'Ebʼ',
     13: 'Bʼen', 14: 'Ix', 15: 'Men', 16: 'Kʼibʼ', 17: 'Kabʼan', 18: 'Etzʼnabʼ',
     19: 'Kawak', 20: 'Ajaw'}

If we want to set a Tzolk’in day of '8 Kabʼan', we can either pass the day number 8 and day name Kabʼan to the constructor, or the day number 8 and the day name number 17.

tzolkin.Tzolkin(number=8, name_str="Kabʼan")
    8 Kabʼan
tzolkin.Tzolkin(number=8, name_number=17)
    8 Kabʼan

If we pass an invalid number (not in [1, 13]) or name to the constructor, we get a TzolkinException.

tzolkin.Tzolkin(number=53, name_number=17)

    TzolkinException: number 53 is not a valid Tzolkin day number, not between 1 and 13 (including 1 and 13)

tzolkin.Tzolkin(number=3, name_str="Hugo")

    TzolkinException: string "Hugo" is not a valid Tzolkin day name, one of: dict_values(['Imix', 'Ikʼ', 'Akʼbʼal', 'Kʼan', 'Chikchan', 'Kimi', 'Manikʼ', 'Lamat', 'Muluk', 'Ok', 'Chuwen', 'Ebʼ', 'Bʼen', 'Ix', 'Men', 'Kʼibʼ', 'Kabʼan', 'Etzʼnabʼ', 'Kawak', 'Ajaw'])

tzolkin.Tzolkin(number=3, name_number=-5)

    TzolkinException: -5 is not a valid Tzolkin day name number, it must be between 1 and 20 (including 1 and 20)

These Tzolk’in day numbers and names can be accessed using the methods getDayNumber, getDayName and getDayNameNumber.

# Set the Tzolk’in date to '12 Kimi'.
tzolkin_date = tzolkin.Tzolkin(number=12, name_str="Kimi")

tzolkin_date.getDayNumber()
    12
tzolkin_date.getDayName()
    'Kimi'
tzolkin_date.getDayNameNumber()
    6

To get the number of Tzolk’in day in the Tzolk’in year of 260 days, there is getTzolkinYearDay. For example '12 Kimi' is the 246. day (of 260 days) of the Tzolk’in year

tzolkin_date.getTzolkinYearDay()
    246

To parse a Tzolk’in day name that isn't exactly like the ones in tzolkin.day_names (see [8]), there is the method Tzolkin.parseTzolkinName, that ignores upper- and lowercase and all non-alphanumeric and non-ascii characters.

day_number = tzolkin.Tzolkin.parseTzolkinName("EtZ`nAB")
if day_number != 0:
    tzolkin_name = tzolkin_calendar.day_names[day_number]
tzolkin_name
    'Etzʼnabʼ'

All 260 Tzolk’in days of a Tzolk’in year we can get as a list of strings from the static method getTzolkinCalendar.

tzolkin.Tzolkin.getTzolkinCalendar()
    ['1 Imix', '2 Ikʼ', '3 Akʼbʼal', '4 Kʼan', '5 Chikchan', '6 Kimi', '7 Manikʼ', '8 Lamat', '9 Muluk', '10 Ok',
     '11 Chuwen',
     ...
                                                                                    '1 Lamat', '2 Muluk', '3 Ok',
     '4 Chuwen', '5 Ebʼ', '6 Bʼen', '7 Ix', '8 Men', '9 Kʼibʼ', '10 Kabʼan', '11 Etzʼnabʼ', '12 Kawak', '13 Ajaw']
Search Gregorian Dates to a given Tzolk’in Date

We can search for the next (forward in time) or last (backwards in time) day with the same Tzolk’in date using the methods getNextDate and getLastDate. Both methods return a datetime.date object.

When searching for the next gregorian date that has the Tzolk’in date '7 Kawak', we get the 28th of March, 2021 - because we started searching 'today', which is the 24th of March 2021.

# Set the Tzolk’in date to search for to '7 Kawak'.
tzolkin_date = tzolkin.Tzolkin(number=7, name_str="Kawak")

tzolkin_date.getNextDate()
    datetime.date(2021, 3, 28)

When searching for the last gregorian date that has the Tzolk’in date '7 Kawak', we get the 11th of July, 2020 - because we started searching 'today', which is the 24th of March 2021.

tzolkin_date.getLastDate()
    datetime.date(2020, 7, 11)

Both methods, getNextDate and getLastDate take an optional argument start_date, which is the gregorian date to start the search. If no start_date is given, 'today' is used as the start date.

So now we search again for '7 Kawak' in both directions, but this time we start at the 10th of July, 2020.

# Set the Tzolk’in date to search for to '7 Kawak'.
tzolkin_date = tzolkin.Tzolkin(number=7, name_str="Kawak")

# Set the start date of the search to the 10th of July, 2020.
start_search = datetime.date.fromisoformat("2020-07-10")

start_search.isoformat()
    '2020-07-10'

For the next day with a Tzolk’in date of '7 Kawak' we now get the 11th of July, 2020.

tzolkin_date.getNextDate(start_date=start_search)
    datetime.date(2020, 7, 11)

For the last day before our start date with a Tzolk’in date of '7 Kawak' we now get the 25th of October, 2019.

tzolkin_date.getLastDate(start_date=start_search)
    datetime.date(2019, 10, 25)

To get a list of datetime.date dates with the same Tzolk’in date, we can use the methods getNextDateList and getLastDateList.

Again, we can set the argument start_date to a gregorian date to start the search or not set it to start the search today. The number of elements in the returned list is set using the parameter list_size, which defaults to 50.

Let's start the search for dates with a Tzolk’in date of ' 7 Kawak' today, the 24th of March 2021, and set the list size to 9 elements:

# Set the Tzolk’in date to search for to '7 Kawak'.
tzolkin_date = tzolkin.Tzolkin(number=7, name_str="Kawak")

tzolkin_date.getNextDateList(list_size=9)
    [datetime.date(2021, 3, 28),
     datetime.date(2021, 12, 13),
     datetime.date(2022, 8, 30),
     datetime.date(2023, 5, 17),
     datetime.date(2024, 2, 1),
     datetime.date(2024, 10, 18),
     datetime.date(2025, 7, 5),
     datetime.date(2026, 3, 22),
     datetime.date(2026, 12, 7)]

Now start searching for '7 Kawak' on the 29th of March, 2021 and set the returned list size to 5.

# Set the start date of the search to the 29th of March, 2021.
start_search = datetime.date.fromisoformat("2021-03-29")

tzolkin_date.getLastDateList(start_date=start_search, list_size=5)
    [datetime.date(2021, 3, 28),
     datetime.date(2020, 7, 11),
     datetime.date(2019, 10, 25),
     datetime.date(2019, 2, 7),
     datetime.date(2018, 5, 23)]
Calculations using Tzolk’in Dates

There are 4 methods to get the difference in days between two Tzolk’in dates and to add (or subtract) days from a Tzolk’in date: addDays, addTimedelta, getDayDiff and getDayTimedelta.

Lets start with a Tzolk’in date of '6 Muluk'.

tzolkin.Tzolkin(number=6, name_str="Muluk")
    6 Muluk

Add 6 days to it, and we get a Tzolk’in date of '12 Men'.

tzolkin.Tzolkin(number=6, name_str="Muluk").addDays(6)
    12 Men

Instead of using ints, we can also add and subtract datetime.timedelta objects. Now subtract 6 days from '12 Men' - we get '6 Muluk'.

to_subtract = datetime.timedelta(days=-6)

tzolkin.Tzolkin(number=12, name_str="Men").addTimedelta(to_subtract)
    6 Muluk

To get the difference between two Tzolk’in dates there exist the Methods getDayDiff and getDayTimedelta.

Lets calculate the difference in days between '6 Muluk' and '12 Men'.

# Set start_tzolkin to '6 Muluk'.
start_tzolkin = tzolkin.Tzolkin(number=6, name_str="Muluk")

# Set end_tzolkin to '12 Men'.
end_tzolkin = tzolkin.Tzolkin(number=12, name_str="Men")

start_tzolkin.getDayDiff(end_tzolkin)
    6

And using getDayTimedelta, which returns a datetime.timedelta object.

start_tzolkin.getDayTimedelta(end_tzolkin)
    datetime.timedelta(days=6)

What happens, if we calculate the difference between '12 Men' and '6 Muluk'?

end_tzolkin.getDayDiff(start_tzolkin)
    254

We get 254 days, not -6. That's because the difference is always calculated forward in time. If you want to get negative days or the shortest possible time difference, subtract 260 from the the result (the number of days in a Tzolk’in year). As soon as the difference in days is greater than 130, to minimum time distance in days 'is negative'.

day_diff = end_tzolkin.getDayDiff(start_tzolkin)

if day_diff > 130:
    day_diff = 260 - day_diff
day_diff
    6

Or you can use the minimum of result and |result - 260| that is abs(result - 260).

day_diff = end_tzolkin.getDayDiff(start_tzolkin)
shortest_diff = min(day_diff, abs(day_diff - 260))
shortest_diff
    6

More information

Detailed information is available at the documentation website.

Contributing

Any help is welcome!

If you encounter a problem using tzolkin-calendar, a task it not as easy as you'd like it to be or you'd like something added to it: open an issue at GitHub.

Report Issues (Bugs and Feature Requests)

File a bug report at Github

Add a feature request at Github

Changing the Documentation and Source Code

If you'd like to contribute directly, e.g. better the documentation, add another language or write some source code: fork tzolkin-calendar by clicking the Fork-button in the upper right corner of the GitHub project website. Check out your fork of tzolkin-calendar using the URL from the Code-button of your fork on Github. The URL should be something like github.com/YOUR_USERNAME/tzolkin-calendar.git.

Details about how to fork a repository on Github are here

and set up the development environment using pipenv.

First, install pipenv if you don't already have it installed:

python -m pip install --upgrade pipenv

and install all needed packages to develop tzolkin-calender:

cd tzolkin-calendar
python -m pipenv install --dev

That command installs all packages in Pipfile/Pipfile.lock in the directory tzolkin-calender, the root directory of tzolkin-calendar.

More information about pipenv can be found at Pipenv.

Make your changes, push them to your forked repository and make a pull-request (e.g. using the Pull request-button above and right of GitHubs source file view).

See GitHub on Pull-Requests

Github Documentation on Collaborating with Issues and Pull Requests

See GitHub's documentation about how to contribute for details: Contributing at Github

More Information

Detailed information is available at the documentation website: Contributing

License

Everything in tzolkin-calendar is licensed under the MIT license, see file LICENSE

Badges

External Checks

DeepSource Maintainability codecov

Static Code Checks

Bandit Black Flake8 Pycodestyle Pydocstyle Pyflakes

Tests

Mac OS X latest Tests Mac OS X latest Ubuntu 20.04 Tests Ubuntu 20.04 Tests Windows 2019

Problem with Unicode output on GitHub's Windows 2019 Server: Windows 2019, see Issue #1

About

Python package and command line client to convert between Tzolk’in and Gregorian dates and calculate with Maya Tzolk’in dates. And a interactive Jupyter Notebook

Topics

Resources

License

Stars

Watchers

Forks