shithub: mc

Download patch

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")
 	;;