ref: 06e5f064ec985d4fd9e530e5a94cf4b1721d64f1
parent: be4be6e3d87229e61cc4676e2e7bb8e995a99803
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Sep 14 18:36:12 EDT 2015
Fix up earlier times.
--- a/lib/date/date.myr
+++ b/lib/date/date.myr
@@ -23,9 +23,9 @@
*/
;;
-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 @@
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 @@
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 @@
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
}
@@ -125,8 +142,6 @@
const sub = {d, dt-> mkinstant(d.actual - (dt castto(std.time)), d.tzname)
}
-
-
const delta = {a, b-> (b.actual - a.actual) castto(delta)
--- a/lib/date/fmt.myr
+++ b/lib/date/fmt.myr
@@ -68,7 +68,7 @@
| '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 @@
| '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.")
--- a/lib/date/test/fmt.myr
+++ b/lib/date/test/fmt.myr
@@ -4,12 +4,30 @@
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--- a/lib/date/test/parse.myr
+++ b/lib/date/test/parse.myr
@@ -7,7 +7,7 @@
/*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");;
--
⑨