ref: 7e02923fe7e9abd65a9b039a832ca593075f8132
dir: /lib/date/date.myr/
use std use "types.use" use "zoneinfo.use" pkg date = /* date i/o */ const parse : (d : byte[:] -> date) const parsefmt : (fmt : byte[:], d : byte[:] -> date) const parsez : (d : byte[:], tz : byte[:] -> date) const fmt : (d : date -> byte[:]) const fmtymd : (d : date -> byte[:]) const bfmt : (buf : byte[:], d : date -> std.size) const bfmtymd : (buf : byte[:], d : date -> std.size) /* useful constructors */ const mkdate : (tm : std.time, tz : diff -> date) const now : (tz : byte[:] -> date) const utcnow : (-> date) const localoff : (-> diff) const tzoff : (tzname : byte[:] -> diff) /* date differences */ const add : (d : date, dt : diff -> date) const diff : (a : date, b : date -> diff) ;; const Unix2Julian = 719468 const Days400y = 365*400 + 4*25 - 3 const Days4y = 365*4 + 1 const fmt = {d -> std.fmt("%04i-%02i-%02i %i:%i:%i", d.year, d.mon, d.day, d.h, d.m, d.s) } const fmtymd = {d -> std.fmt("%04i-%02i-%02i", d.year, d.mon, d.day) } const bfmt = {buf, d -> std.bfmt(buf, "%04i-%02i-%02i %i:%i:%i", d.year, d.mon, d.day, d.h, d.m, d.s) } const bfmtymd = {buf, d -> std.bfmt(buf, "%04i-%02i-%02i", d.year, d.mon, d.day) } const now = {tz : byte[:] var tm tm = std.now() -> mkdate(tm, _zoneinfo.findtzoff(tz, tm)) } const utcnow = { -> mkdate(std.now(), 0) } const mkdate = {tm, off var j, y, m, d var t, e var date date.actual = tm date.tzoff = off tm += off castto(std.time) t = tm % (24*60*60*1_000_000) /* time */ e = tm / (24*60*60*1_000_000) /* epoch days */ /* microseconds, seconds, minutes, hours */ date.us = (t % 1_000_000) castto(int) t /= 1_000_000 date.s = (t % 60) castto(int) t /= 60 date.m = (t % 60) castto(int) t /= 60 date.h = t castto(int) /* weekday */ date.wday = ((e + 4) % 7) castto(int) /* the world started on Thursday */ /* year, month, day: Implemented according to "Algorithm 199, conversions between calendar date and Julian day number", Robert G. Tantzen, Air Force Missile Development Center, Holloman AFB, New Mex. Lots of magic. Yer a wizard, 'arry. */ j = e + Unix2Julian y = (4 * j - 1) / Days400y j = 4 * j - 1 - Days400y * y d = j / 4 j = (4 * d + 3) / Days4y d = 4 * d + 3 - Days4y * j d = (d + 4) / 4 ; m = (5 * d - 3) / 153 d = 5 * d - 3 - 153 * m d = (d + 5) / 5 y = 100 * y + j if m < 10 m += 3 else m -= 9 y++ ;; date.year = y castto(int) date.mon = m castto(int) date.day = (d + 1) castto(int) -> date } const ndays = {y if y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) -> 366 else -> 365 ;; }