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
;;
}