shithub: mc

Download patch

ref: 19e038b0670828810453c284589469c6520aa7d9
parent: 06e5f064ec985d4fd9e530e5a94cf4b1721d64f1
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Sep 14 18:50:05 EDT 2015

Fix dates in the BC

--- a/lib/date/date.myr
+++ b/lib/date/date.myr
@@ -26,6 +26,7 @@
 const Days400y	= 365*400 + 4*25 - 3
 const Days4y	= 365*4 + 1
 const DayUsec	= (24*60*60*1_000_000)
+const Mdays	= [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
 
 const utcnow = {
 	-> mkinstant(std.now(), "")
@@ -70,10 +71,13 @@
 	inst.us  = (t % 1_000_000) castto(int)
 	t /= 1_000_000
 	inst.s = (t % 60) castto(int)
+	std.assert(inst.s >= 0, "inst.s negative??\n")
 	t /= 60
 	inst.m = (t % 60) castto(int)
+	std.assert(inst.m >= 0, "inst.m negative??\n")
 	t /= 60
 	inst.h = t castto(int)
+	std.assert(inst.h >= 0, "inst.h negative??\n")
 
 	/* weekday */
 	inst.wday = ((e + 4) % 7) castto(int)	/* the world started on Thursday */
@@ -88,9 +92,7 @@
 	Lots of magic. Yer a wizard, 'arry.
 	*/
 	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
@@ -115,6 +117,13 @@
 	/* there's no year 0 */
 	if y <= 0
 		y--
+	;;
+	/* and if j negative, the day and month are also negative */
+	if m < 0
+		m += 12
+	;;
+	if d < 0
+		d += Mdays[m - 1] 
 	;;
 
 	inst.year = y castto(int)
--- a/lib/date/fmt.myr
+++ b/lib/date/fmt.myr
@@ -22,6 +22,7 @@
 const Timefmt	= "%h:%m:{} %z"
 const Datefmt	= "%Y-%m-%d %z"
 
+/* Always formats in proleptic Gregorian format */
 const sbfmt = {sb, ap, opts
 	var d : instant
 	var fmt
--- a/lib/date/test/fmt.myr
+++ b/lib/date/test/fmt.myr
@@ -28,6 +28,10 @@
 	/* large negative time stamp */
 	d = date.mkinstant(-50000000000*1_000_000, "")
 	eq("385-7-25 07:06:40 +0000", std.bfmt(buf[:], "{D}", d))
+
+	/* date in the bc */
+	d = date.mkinstant(-70000000000*1_000_000, "")
+	eq("-249-11-19 19:33:20 +0000", std.bfmt(buf[:], "{D}", d))
 }
 
 const eq = {expected, actual