/* Like datefmt, but for the Mayan calendars */ /* Needs cleanup */ #include #include /* Unix epoch, Jan 1, 1970, is "13 Chikchan 3 K'ank'in, 12.17.16.7.5" */ /* Tzolk'in: 260-day count */ /* 20 names, 13 numbers, both incrementing daily */ /* Numbers used were 1-13 */ char *tzolkin_d[]= { "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", }; /* Haab': 365-day count */ /* 18 months of 20 days, plus five days */ /* Days of the month went from 0-19 (per most research) */ char *haab_m[]= { "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'", }; /* Long Count */ /* Most inscriptions usually used just the first 5 places */ /* K'in (day) */ /* Winal is 20 K'in */ /* Tun is 18 Winal */ /* K'atun is 20 Tun */ /* B'ak'tun is 20 K'atun */ /* Piktun is 20 B'ak'tun */ /* Kalabtun is 20 Piktun */ /* K'inchiltun is 20 Kalabtun */ /* Alautun is 20 K'inchiltun */ /* Codes: aAbB dD H kK LmMnN rR tTuU wW X Z % */ typedef struct Lc { int kin; int winal; int tun; int katun; int baktun; int piktun; int kalabtun; int kinchiltun; int alautun; } Lc; typedef struct Maya_t { int trecena; int name; int hdn; /* Haab' day number; internal only. */ int number; int month; Lc longcount; } Maya_t; char *format_t(char *, Maya_t); Maya_t* init(long); ulong now; void usage(void) { fprint(2, "usage: %s [-t seconds] format\n", argv0); exits("usage"); } void main(int argc, char *argv[]) { Maya_t *now_m; now = time(0); ARGBEGIN{ case 't': now = strtoul(EARGF(usage()), 0, 0); break; default: usage(); }ARGEND if(! argc == 1) usage(); now_m = init(now); print("%s", format_t(argv[0], *now_m)); exits(0); } /* Generate a Maya_t; analogous to /sys/src/libc/9sys/ctime.c:/^gmtime */ Maya_t* init(long tim) { long day; long d_winal, d_tun, d_katun, d_baktun; /* Days per winal, &c. */ static Maya_t mt; /* * break initial number into days */ day = tim / 86400L; if(tim % 86400L < 0) day -= 1; d_winal=20; d_tun=20*18; d_katun=20*18*20; d_baktun=20*18*20*20; mt.trecena=((12+day)%13)+1; /* 1-13, not 0-12 */ mt.name=(4+day)%20; mt.hdn=(263+day)%365; mt.number=(mt.hdn)%20; mt.month=(((mt.hdn)/20))%19; /* Pick & set an epoch. Make sure mt.longcount & day match. */ mt.longcount.alautun=0; mt.longcount.kinchiltun=0; mt.longcount.kalabtun=0; mt.longcount.piktun=0; mt.longcount.baktun=12; mt.longcount.katun=17; mt.longcount.tun=16; mt.longcount.winal=7; mt.longcount.kin=5; if(day>0) { mt.longcount.kin = (mt.longcount.kin + day)%20; day -= mt.longcount.kin-5; mt.longcount.winal = (mt.longcount.winal + day/d_winal)%18; day -= (mt.longcount.winal-7)*d_winal; mt.longcount.tun = (mt.longcount.tun + day/d_tun)%20; day -= (mt.longcount.tun-16)*d_tun; mt.longcount.katun = (mt.longcount.katun + day/d_katun)%20; day -= (mt.longcount.katun-17)*d_katun; mt.longcount.baktun = (mt.longcount.baktun + day/d_baktun)%20; // day -= (mt.longcount.baktun-12)*d_baktun; } else if(day<0) { print("NEGATIVE DAY: BOGUS VALUES! "); ; } return &mt; } char * format_t(char *format, Maya_t m) { char *outb; int i; outb=""; for(i = 0; i < strlen(format); i++){ if(format[i] != '%') { outb=smprint("%s%c", outb, format[i]); } else switch(format[++i]){ /* Tzolk'in dates "1 Imix'", "12 Men", &c */ case 'T': outb=smprint("%s%s", outb, format_t("%R %N", m)); break; case 'r': outb=smprint("%s%.2d", outb, m.trecena); break; case 'R': outb=smprint("%s%d", outb, m.trecena); break; // case 'n': // outb=smprint("%s%.2d", outb, m.name); // break; case 'N': outb=smprint("%s%s", outb, tzolkin_d[m.name]); break; /* Haab' dates "0 Pop", "3 Wo", &c */ case 'H': outb=smprint("%s%s", outb, format_t("%D %M", m)); break; case 'd': outb=smprint("%s%.2d", outb, m.number); break; case 'D': outb=smprint("%s%d", outb, m.number); break; case 'm': outb=smprint("%s%.2d", outb, m.month); break; case 'M': outb=smprint("%s%s", outb, haab_m[m.month]); break; /* Written together as "1 Imix' 0 Pop", "12 Men 3 Wo", &c */ case 'X': outb=smprint("%s%s", outb, format_t("%T %H", m)); break; /* Long Count and components */ case 'L': outb=smprint("%s%s", outb, format_t("%B.%A.%U.%W.%K", m)); break; case 'k': outb=smprint("%s%.2d", outb, m.longcount.kin); break; case 'K': outb=smprint("%s%d", outb, m.longcount.kin); break; case 'w': outb=smprint("%s%.2d", outb, m.longcount.winal); break; case 'W': outb=smprint("%s%d", outb, m.longcount.winal); break; case 'u': outb=smprint("%s%.2d", outb, m.longcount.tun); break; case 'U': outb=smprint("%s%d", outb, m.longcount.tun); break; case 'a': outb=smprint("%s%.2d", outb, m.longcount.katun); break; case 'A': outb=smprint("%s%d", outb, m.longcount.katun); break; case 'b': outb=smprint("%s%.2d", outb, m.longcount.baktun); break; case 'B': outb=smprint("%s%d", outb, m.longcount.baktun); break; /* Need higher-order long count places */ /* Everything together. How were these really written? */ case 'Z': outb=smprint("%s%s", outb, format_t("%X %L", m)); break; case '+': outb=smprint("%s%s\n", outb, format_t("%Z", m)); break; /* Literals and others */ case ' ': outb=smprint("%s%s", outb, "% "); break; case '%': outb=smprint("%s%s", outb, "%"); break; case 'n': outb=smprint("%s%s", outb, "\n"); break; case 't': outb=smprint("%s%s", outb, " "); break; default: break; } } return outb; }