ref: 9befecb14dfadec7f097d54065793d209cc6eb92
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) const time : (d : date -> std.time) /* date differences */ const add : (d : date, dt : diff -> date) const diff : (a : date, b : date -> diff) ;; const UnixJulianDiff = 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 + UnixJulianDiff 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 time = {date var t var c, y, ya, m, u t = 0 if date.mon > 2 m = (date.mon - 3) castto(std.time) else m = (date.mon + 9) castto(std.time) y = (date.year - 1) castto(std.time) ;; c = y / 100 ya = y - 100 * c u = (146097 * c) / 4 + \ (1461 * ya) / 4 + \ (153 * m + 2) / 5 + \ (date.day castto(std.time)) + \ UnixJulianDiff t += (u * 24*60*60*1_000_000) t += (date.h castto(std.time)) * 60*60*1_000_000 t += (date.m castto(std.time)) * 60*1_000_000 t += (date.s castto(std.time)) * 1_000_000 t += date.us castto(std.time) -> t } const ndays = {y if y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) -> 366 else -> 365 ;; }