Mayan calendar: Difference between revisions
Content deleted Content added
m Improved coding. |
|||
(5 intermediate revisions by 2 users not shown) | |||
Line 294:
2020-02-29 13.00.07.05.06 4 Kimi 14 K'ayab G7
2020-03-01 13.00.07.05.07 5 Manik' 15 K'ayab G8
</pre>
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <chrono>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
const std::vector<std::string> 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" };
const std::vector<std::string> 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'" };
int32_t positive_modulus(const int32_t& base, const int32_t& modulus) {
const int32_t result = base % modulus;
return ( result < 0 ) ? result + modulus : result;
}
std::chrono::sys_days create_date(const std::string& iso_date) {
const int year = std::stoi(iso_date.substr(0, 4));
const unsigned int month = std::stoi(iso_date.substr(5, 7));
const unsigned int day = std::stoi(iso_date.substr(8, 10));
std::chrono::year_month_day date{std::chrono::year{year}, std::chrono::month{month}, std::chrono::day{day}};
return std::chrono::sys_days(date);
}
const std::chrono::sys_days CREATION_TZOLKIN = create_date("2012-12-21");
const std::chrono::sys_days ZERO_HAAB = create_date("2019-04-02");
int32_t days_per_mayan_month(const std::string& month) {
return ( month == "Wayeb'" ) ? 5 : 20;
}
std::string tzolkin(const std::chrono::sys_days& gregorian) {
const int32_t days_between = ( gregorian - CREATION_TZOLKIN ).count();
int32_t remainder = positive_modulus(days_between, 13);
remainder += ( remainder <= 9 ) ? 4 : -9;
return std::to_string(remainder) + " " + Tzolkin[positive_modulus(days_between - 1, 20)];
}
std::string haab(const std::chrono::sys_days& gregorian) {
const int32_t days_between = ( gregorian - ZERO_HAAB ).count();
int32_t remainder = positive_modulus(days_between, 365);
const std::string month = Haab[positive_modulus(remainder + 1, 20)];
const int32_t day_of_month = remainder % 20 + 1;
return ( day_of_month < days_per_mayan_month(month) ) ?
std::to_string(day_of_month) + " " + month : "Chum " + month;
}
std::string long_count(const std::chrono::sys_days& gregorian) {
int32_t days_between = ( gregorian - CREATION_TZOLKIN ).count() + 13 * 360 * 400;
const int32_t baktun = positive_modulus(days_between, 360 * 400);
days_between = days_between % ( 360 * 400 );
const int32_t katun = days_between / ( 20 * 360 );
days_between = days_between % ( 20 * 360 );
const int32_t tun = days_between / 360;
days_between = days_between % 360;
const int32_t winal = days_between / 20;
const int32_t kin = days_between % 20;
std::string result = "";
for ( int32_t number : { baktun, katun, tun, winal, kin } ) {
std::string value = std::to_string(number) + ".";
result += ( number <= 9 ) ? "0" + value : value;
}
return result.substr(0, result.length() - 1);
}
std::string lords_of_the_night(const std::chrono::sys_days& gregorian) {
const int32_t days_between = ( gregorian - CREATION_TZOLKIN ).count();
const int32_t remainder = days_between % 9;
return "G" + std::to_string( ( remainder <= 0 ) ? remainder + 9 : remainder );
}
int main() {
const std::vector<std::string> iso_dates = { "2004-06-19", "2012-12-18", "2012-12-21", "2019-01-19",
"2019-03-27", "2020-02-29", "2020-03-01", "2071-05-16", "2020-02-02" };
std::cout << "Gregorian Long Count Tzolk'in Haab' Lords of the Night" << std::endl;
std::cout << "------------------------------------------------------------------------------" << std::endl;
for ( const std::string& iso_date : iso_dates ) {
const std::chrono::sys_days date = create_date(iso_date);
std::cout << std::left << std::setw(15) << iso_date << std::setw(19) << long_count(date)
<< std::setw(12) << tzolkin(date) << std::setw(18) << haab(date)
<< lords_of_the_night(date) << std::endl;
}
}
</syntaxhighlight>
{{ out }}
<pre>
Gregorian Long Count Tzolk'in Haab' Lords of the Night
------------------------------------------------------------------------------
2004-06-19 12.19.11.06.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.00.00.00.00 4 Ajaw 3 K'ank'in G9
2019-01-19 13.00.06.03.00 1 Ajaw 13 Muwan G6
2019-03-27 13.00.06.06.07 3 Manik' Chum Wayeb' G1
2020-02-29 13.00.07.05.06 4 Kimi 14 K'ayab G7
2020-03-01 13.00.07.05.07 5 Manik' 15 K'ayab G8
2071-05-16 13.02.19.04.10 1 Ok 18 Sip G9
2020-02-02 13.00.07.03.19 3 Kawak 7 Pax G7
</pre>
Line 683 ⟶ 791:
System.out.println("------------------------------------------------------------------------------");
for ( LocalDate date : testDates ) {
System.out.println(String.format("%-15s%-19s%-12s%-
date.toString(), longCount(date), tzolkin(date), haab(date), lordsOfTheNight(date)));
}
Line 716 ⟶ 824:
long daysBetween = ChronoUnit.DAYS.between(ZERO_HAAB, aGregorian);
int remainder = Math.floorMod(daysBetween, 365);
String month = Haab.get(Math.floorDiv(remainder + 1, 20));
return ( dayOfMonth < daysPerMayanMonth(month) ) ? dayOfMonth + " " + month : "Chum " + month;
}
Line 747 ⟶ 855:
Gregorian Long Count Tzolk'in Haab' Lords of the Night
------------------------------------------------------------------------------
2004-06-19 12.19.11.06.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.00.00.00.00 4 Ajaw 3 K'ank'in G9
2019-01-19 13.00.06.03.00 1 Ajaw 13 Muwan G6
2019-03-27 13.00.06.06.07 3 Manik' Chum Wayeb' G1
2020-02-29 13.00.07.05.06 4 Kimi 14 K'ayab G7
2020-03-01 13.00.07.05.07 5 Manik' 15 K'ayab G8
2071-05-16 13.02.19.04.10 1 Ok 18 Sip G9
2020-02-02 13.00.07.03.19 3 Kawak 7 Pax G7
</pre>
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
'''Works with jq, the C implementation of jq'''
'''Works with gojq, the Go implementation of jq'''
In this entry, the functions for converting Gregorian dates to dates
in the Mayan calendar take the form of zero-arity filters that expect,
as input, strings of the form "yyyy-mm-dd" or JSON Date objects of the
form {"year", "month", "day"}.
<syntaxhighlight lang="jq">
### General utilities
def lpad($len): tostring | ($len - length) as $l | (" " * $l) + .;
def rpad($len): tostring | ($len - length) as $l | . + (" " * $l);
# days_between("2020-01-01"; "2020-01-02") #=> 1
# days_between("2020-01-02"; "2020-01-01") #=> -1
def days_between($yyyymmddBefore; $yyyymmddAfter):
(yyyymmddBefore | strptime("%Y-%m-%d") | mktime) as $before
| (yyyymmddAfter | strptime("%Y-%m-%d") | mktime) as $after
# leap seconds are always inserted
| (($after - $before) / (24*60*60) | floor) ;
### `Date` objects
def Date($year; $month; $day): {$year, $month, $day};
# Convert a Date object to a string yyyy-mm-dd
# Other inputs are (currently) unscathed.
def yyyymmdd:
if type == "object" then "\(.year)-\(.month)-\(.day)"
else .
end;
### Mayan Calendar
def 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(" ");
def 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(" ");
def CREATION_TZOLKIN: "2012-12-21";
# Input: Date or yyyy-mm-dd
def tzolkin:
(days_between(CREATION_TZOLKIN; yyyymmdd)) as $diff
| {rem: ($diff % 13)}
| if .rem < 0 then .rem += 13 end
| .num = (if .rem <= 9 then .rem + 4 else .rem - 9 end)
| .rem = $diff % 20
| if .rem <= 0 then .rem += 20 end
| [.num, sacred[.rem-1] ] ;
# Input: Date or yyyy-mm-dd
def haab:
def ZERO_HAAB: "2019-04-02";
(days_between(ZERO_HAAB; yyyymmdd)) as $diff
| {rem: ($diff % 365)}
| if .rem < 0 then .rem += 365 end
| .month = civil[((.rem+1)/20)|floor]
| .last = (if .month == "Wayeb'" then 5 else 20 end)
| .d = .rem%20 + 1
| if .d < .last then [(.d|tostring), .month]
else ["Chum", .month]
end;
# Input: Date or yyyy-mm-dd
def longCount:
{diff: days_between(CREATION_TZOLKIN; yyyymmdd)}
| .diff += 13*400*360
| .baktun = ((.diff/(400*360)) | floor)
| .diff = .diff % (400*360)
| .katun = ((.diff/(20 * 360))|floor)
| .diff = .diff % (20*360)
| .tun = ((.diff/360)|floor)
| .diff = .diff % 360
| .winal = ((.diff/20)|floor)
| .kin = .diff % 20
| [.baktun, .katun, .tun, .winal, .kin]
| join(".");
# Input: Date or yyyy-mm-dd
def lord:
{diff: days_between(CREATION_TZOLKIN; yyyymmdd)}
| .rem = .diff % 9
| if .rem <= 0 then .rem += 9 end
| "G\(.rem)";
def 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"
];
" Gregorian Tzolk’in Haab’ Long Lord of",
" Date # Name Day Month Count the Night",
"---------- -------- ------------- -------------- ---------",
# Date.default = Date.isoDate
(dates[]
| tzolkin as [$n, $s]
| haab as [$d, $m]
| [., ($n | lpad(4)), ($s | rpad(8)), ($d|lpad(4)), ($m|rpad(8)), (longCount|lpad(20)), (lord|lpad(6))]
| join(" ")
)
</syntaxhighlight>
{{output}}
<pre>
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
</pre>
Line 813 ⟶ 1,057:
rpad(haab(date), 15), nightlord(date))
end
</syntaxhighlight>
{{out}}
<pre>
Gregorian Long Count Tzolk´in Haab´ Nightlord
Line 1,364 ⟶ 1,609:
{{libheader|Wren-date}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="
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(" ")
|