1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
#!/usr/bin/env python
#
# Copyright (c) 2013 Daniil Baturin <daniil at baturin dot org>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import sys
class MayaDate(object):
""" Converts number of days since UNIX epoch
to the Maya calendar date.
Ancient Maya people used three independent calendars for
different purposes.
Long count calendar is for recording historical events.
It and represents the number of days passed
since some date in the past the Maya believed is the day
our world was created.
Tzolkin calendar is for religious purposes, it has
two independent cycles of 13 and 20 days, where 13 day
cycle days are numbered, and 20 day cycle days are named.
Haab calendar is for agriculture and daily life, it's a
365 day calendar with 18 months 20 days each, and 5
nameless days.
The smallest unit of long count calendar is one day (kin)
"""
""" The long count calendar uses five different base 18 or base 20
cycles. Long-count date is writtin in dot separated format
from longest to shortest cycle,
<baktun>.<katun>.<tun>.<winal>.<kin>
for example, "13.0.0.9.2".
Classic version actually used by the ancient Maya wraps around
every 13th baktun, but modern researchers often use longer cycles
such as piktun = 20 baktun.
"""
kin = 1
winal = 20 # 20 kin
tun = 360 # 18 winal
katun = 7200 # 20 tun
baktun = 144000 # 20 katun
""" Tzolk'in date is composed of two independent cycles.
Dates repeat every 260 days, 13 Ajaw is considered the end
of tzolk'in.
Every day of the 20 day cycle has unique name, we number
them from zero so it's easier to map remainder to day:
"""
tzolkin_days = { 0: "Imix'",
1: "Ik'",
2: "Ak'b'al",
3: "K'an",
4: "Chikchan",
5: "Kimi",
6: "Manik'",
7: "Lamat",
8: "Muluk",
9: "Ok",
10: "Chuwen",
11: "Eb'",
12: "B'en",
13: "Ix",
14: "Men",
15: "Kib'",
16: "Kab'an",
17: "Etz'nab'",
18: "Kawak",
19: "Ajaw" }
""" As said above, haab (year) has 19 months. Only 18 are
true months of 20 days each, the remaining 5 days called "wayeb"
do not really belong to any month, but we think of them as a pseudo-month
for convenience.
Also, note that days of the month are actually numbered from 0, not from 1,
it's not for technical reasons.
"""
haab_months = { 0: "Pop",
1: "Wo'",
2: "Sip",
3: "Sotz'",
4: "Sek",
5: "Xul",
6: "Yaxk'in'",
7: "Mol",
8: "Ch'en",
9: "Yax",
10: "Sak'",
11: "Keh",
12: "Mak",
13: "K'ank'in",
14: "Muwan'",
15: "Pax",
16: "K'ayab",
17: "Kumk'u",
18: "Wayeb'" }
""" Now we need to map the beginning of UNIX epoch
(Jan 1 1970 00:00 UTC) to the beginning of the long count
calendar (0.0.0.0.0, 4 Ajaw, 8 Kumk'u).
The problem with mapping the long count calendar to
any other is that its start date is not known exactly.
The most widely accepted hypothesis suggests it was
August 11, 3114 BC gregorian date. In this case UNIX epoch
starts on 12.17.16.7.5, 13 Chikchan, 3 K'ank'in
It's known as Goodman-Martinez-Thompson (GMT) correlation
constant.
"""
start_days = 1856305
""" Seconds in day, for conversion from timestamp """
seconds_in_day = 60 * 60 * 24
def __init__(self, timestamp):
if timestamp is None:
self.days = self.start_days
else:
self.days = self.start_days + (int(timestamp) // self.seconds_in_day)
def long_count_date(self):
""" Returns long count date string """
days = self.days
cur_baktun = days // self.baktun
days = days % self.baktun
cur_katun = days // self.katun
days = days % self.katun
cur_tun = days // self.tun
days = days % self.tun
cur_winal = days // self.winal
days = days % self.winal
cur_kin = days
longcount_string = "{0}.{1}.{2}.{3}.{4}".format( cur_baktun,
cur_katun,
cur_tun,
cur_winal,
cur_kin )
return(longcount_string)
def tzolkin_date(self):
""" Returns tzolkin date string """
days = self.days
""" The start date is not the beginning of both cycles,
it's 4 Ajaw. So we need to add 4 to the 13 days cycle day,
and substract 1 from the 20 day cycle to get correct result.
"""
tzolkin_13 = (days + 4) % 13
tzolkin_20 = (days - 1) % 20
tzolkin_string = "{0} {1}".format(tzolkin_13, self.tzolkin_days[tzolkin_20])
return(tzolkin_string)
def haab_date(self):
""" Returns haab date string.
The time start on 8 Kumk'u rather than 0 Pop, which is
17 days before the new haab, so we need to substract 17
from the current date to get correct result.
"""
days = self.days
haab_day = (days - 17) % 365
haab_month = haab_day // 20
haab_day_of_month = haab_day % 20
haab_string = "{0} {1}".format(haab_day_of_month, self.haab_months[haab_month])
return(haab_string)
def date(self):
return("{0}, {1}, {2}".format( self.long_count_date(), self.tzolkin_date(), self.haab_date() ))
try:
timestamp = sys.argv[1]
except:
print("Please specify timestamp in the argument")
sys.exit(1)
maya_date = MayaDate(timestamp)
print(maya_date.date())
|