diff options
-rw-r--r-- | op-mode-definitions/show-date.xml | 2 | ||||
-rwxr-xr-x | src/op_mode/maya_date.py | 209 |
2 files changed, 210 insertions, 1 deletions
diff --git a/op-mode-definitions/show-date.xml b/op-mode-definitions/show-date.xml index dddecd2fb..705172b39 100644 --- a/op-mode-definitions/show-date.xml +++ b/op-mode-definitions/show-date.xml @@ -18,7 +18,7 @@ <properties> <help>Show UTC date in Maya calendar format</help> </properties> - <command>${vyatta_bindir}/maya-date.py $(date +%s)</command> + <command>${vyos_op_scripts_dir}/maya_date.py $(date +%s)</command> </leafNode> </children> </node> diff --git a/src/op_mode/maya_date.py b/src/op_mode/maya_date.py new file mode 100755 index 000000000..7d8aefc91 --- /dev/null +++ b/src/op_mode/maya_date.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2013, 2018 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +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. + + The long count calendar is for recording historical events. + It 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 the long count calendar is one day (kin). + + """ + + """ The long count calendar uses five different base 18 or base 20 + cycles. Modern scholars write long count calendar dates in a 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 historians 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 the 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() )) + +if __name__ == '__main__': + try: + timestamp = sys.argv[1] + except: + print("Please specify timestamp in the argument") + sys.exit(1) + + maya_date = MayaDate(timestamp) + print(maya_date.date()) |