diff options
author | Ori Bernstein <ori@eigenstate.org> | 2015-09-14 22:36:12 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2015-09-14 22:37:14 -0700 |
commit | 06e5f064ec985d4fd9e530e5a94cf4b1721d64f1 (patch) | |
tree | 9aa39d46d138403bff38b3e8ff93d011a06aee94 /lib/date | |
parent | be4be6e3d87229e61cc4676e2e7bb8e995a99803 (diff) | |
download | mc-06e5f064ec985d4fd9e530e5a94cf4b1721d64f1.tar.gz |
Fix up earlier times.
Diffstat (limited to 'lib/date')
-rw-r--r-- | lib/date/date.myr | 37 | ||||
-rw-r--r-- | lib/date/fmt.myr | 4 | ||||
-rw-r--r-- | lib/date/test/fmt.myr | 26 | ||||
-rw-r--r-- | lib/date/test/parse.myr | 2 |
4 files changed, 51 insertions, 18 deletions
diff --git a/lib/date/date.myr b/lib/date/date.myr index dcc5149..ed17133 100644 --- a/lib/date/date.myr +++ b/lib/date/date.myr @@ -23,9 +23,9 @@ pkg date = */ ;; -const UnixJulianDiff = 719468 const Days400y = 365*400 + 4*25 - 3 const Days4y = 365*4 + 1 +const DayUsec = (24*60*60*1_000_000) const utcnow = { -> mkinstant(std.now(), "") @@ -58,18 +58,22 @@ const mkinstant = {tm, tz tm += off castto(std.time) /* break up time */ - t = tm % (24*60*60*1_000_000) /* time */ - e = tm / (24*60*60*1_000_000) /* epoch days */ + t = tm % DayUsec /* time */ + e = tm / DayUsec /* epoch day */ + if t < 0 + t += DayUsec + e -= 1 + ;; /* microseconds, seconds, minutes, hours */ - inst.us = (t % 1_000_000) castto(int) + inst.us = (t % 1_000_000) castto(int) t /= 1_000_000 - inst.s = (t % 60) castto(int) + inst.s = (t % 60) castto(int) t /= 60 - inst.m = (t % 60) castto(int) + inst.m = (t % 60) castto(int) t /= 60 - inst.h = t castto(int) + inst.h = t castto(int) /* weekday */ inst.wday = ((e + 4) % 7) castto(int) /* the world started on Thursday */ @@ -83,16 +87,23 @@ const mkinstant = {tm, tz Lots of magic. Yer a wizard, 'arry. */ - j = e + UnixJulianDiff + j = (tm + 2440588 * DayUsec) / DayUsec + std.put("j = {}\n", j) + j -= 1721119 + std.assert(j > 0, "date too negative") + 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 @@ -100,9 +111,15 @@ const mkinstant = {tm, tz m -= 9 y++ ;; + + /* there's no year 0 */ + if y <= 0 + y-- + ;; + inst.year = y castto(int) inst.mon = m castto(int) - inst.day = (d + 1) castto(int) + inst.day = d castto(int) -> inst } @@ -126,8 +143,6 @@ const sub = {d, dt -> mkinstant(d.actual - (dt castto(std.time)), d.tzname) } - - const delta = {a, b -> (b.actual - a.actual) castto(delta) } diff --git a/lib/date/fmt.myr b/lib/date/fmt.myr index 3297076..3088e00 100644 --- a/lib/date/fmt.myr +++ b/lib/date/fmt.myr @@ -68,7 +68,7 @@ const datefmt = {sb, fmt, d | 'k': std.sbfmt(sb, "{}", d.h) | 'l': std.sbfmt(sb, "{}", d.h % 12) | 'm': std.sbfmt(sb, "{}", d.mon) - | 'M': std.sbfmt(sb, "{}", d.m) + | 'M': std.sbfmt(sb, "{p=0,w=2}", d.m) | 'n': std.sbfmt(sb, "\n") | 'O': std.sbfmt(sb, "unsupported %O") | 'p': std.sbfmt(sb, "{}", ["AM", "PM"][d.h/12]) @@ -76,7 +76,7 @@ const datefmt = {sb, fmt, d | 'r': datefmt(sb, "%H:%M:%S %P", d) | 'R': datefmt(sb, "%H:%M %P", d) | 's': std.sbfmt(sb, "{}", d.actual) - | 'S': std.sbfmt(sb, "{}", d.s) + | 'S': std.sbfmt(sb, "{p=0,w=2}", d.s) | 't': std.sbfmt(sb, "\t") | 'u': std.sbfmt(sb, "{}", d.wday) | 'U': std.sbfmt(sb, "week number... unimplemented.") diff --git a/lib/date/test/fmt.myr b/lib/date/test/fmt.myr index c00b5d2..1069c86 100644 --- a/lib/date/test/fmt.myr +++ b/lib/date/test/fmt.myr @@ -4,12 +4,30 @@ use date const main = { var buf : byte[1024] var d - var f - /*Fri 29 Aug 2014 07:47:43 PM UTC*/ + /* epoch */ + d = date.mkinstant(0, "") + eq("1970-1-01 00:00:00 +0000", std.bfmt(buf[:], "{D}", d)) + + /* epoch + 12 hours */ + d = date.mkinstant(12*3600*1_000_000, "") + eq("1970-1-01 12:00:00 +0000", std.bfmt(buf[:], "{D}", d)) + + /* epoch - 6 hours */ + d = date.mkinstant(-6*3600*1_000_000, "") + eq("1969-12-31 18:00:00 +0000", std.bfmt(buf[:], "{D}", d)) + + /* epoch - 12 hours */ + d = date.mkinstant(-12*3600*1_000_000, "") + eq("1969-12-31 12:00:00 +0000", std.bfmt(buf[:], "{D}", d)) + + /* more or less random: Fri 29 Aug 2014 07:47:43 PM UTC*/ d = date.mkinstant(1_409_341_663*1_000_000, "") - f = std.bfmt(buf[:], "{D}", d) - eq("2014-8-29 19:47:43 +0000", f) + eq("2014-8-29 19:47:43 +0000", std.bfmt(buf[:], "{D}", d)) + + /* large negative time stamp */ + d = date.mkinstant(-50000000000*1_000_000, "") + eq("385-7-25 07:06:40 +0000", std.bfmt(buf[:], "{D}", d)) } const eq = {expected, actual diff --git a/lib/date/test/parse.myr b/lib/date/test/parse.myr index 0f99cb0..b560080 100644 --- a/lib/date/test/parse.myr +++ b/lib/date/test/parse.myr @@ -7,7 +7,7 @@ const main = { /*Fri 29 Aug 2014 07:47:43 PM UTC*/ match date.parsefmt("%Y-%m-%d %z", "1932-10-23 +0500") | `std.Some d: - eq(std.bfmt(buf[:], "{D}", d), "1932-10-23 00:0:0 +0500") + eq(std.bfmt(buf[:], "{D}", d), "1932-10-23 00:00:00 +0500") | `std.None: std.fatal("Failed to parse date") ;; |