summaryrefslogtreecommitdiff
path: root/lib/date
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-09-14 22:36:12 -0700
committerOri Bernstein <ori@eigenstate.org>2015-09-14 22:37:14 -0700
commit06e5f064ec985d4fd9e530e5a94cf4b1721d64f1 (patch)
tree9aa39d46d138403bff38b3e8ff93d011a06aee94 /lib/date
parentbe4be6e3d87229e61cc4676e2e7bb8e995a99803 (diff)
downloadmc-06e5f064ec985d4fd9e530e5a94cf4b1721d64f1.tar.gz
Fix up earlier times.
Diffstat (limited to 'lib/date')
-rw-r--r--lib/date/date.myr37
-rw-r--r--lib/date/fmt.myr4
-rw-r--r--lib/date/test/fmt.myr26
-rw-r--r--lib/date/test/parse.myr2
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")
;;