shithub: libmujs

Download patch

ref: e4cafa6d265d4ff76ed3e34db41a03a9dfc03866
parent: 5961e3907337e9caa595e37e77b6a0be46549046
author: Tor Andersson <tor@ccxvii.net>
date: Mon Mar 3 18:03:16 EST 2014

Always use ISO 8601 formats for date string formatting.

Simplifies the date formatting code and makes it possible
to round-trip Date.parse(new Date().toString()).

--- a/jsdate.c
+++ b/jsdate.c
@@ -311,62 +311,40 @@
 	return UTC(t);
 }
 
-/* strftime based date formatting */
+/* date formatting */
 
-#define FMT_DATE "%Y-%m-%d"
-#define FMT_TIME "%H:%M:%S"
-#define FMT_DATETIME "%Y-%m-%d %H:%M:%S %z"
-#define FMT_DATETIME_ISO "%Y-%m-%dT%H:%M:%SZ"
-
-static void fmtdate(char *buf, const char *fmt, double t, float tza)
+static char *fmtdate(char *buf, double t)
 {
-	char *p = buf;
-	const char *s = fmt;
-	int tzsign, tzhh, tzmm;
-	while (*s) {
-		if (*s == '%') {
-			switch (s[1]) {
-			default: *p++ = s[0]; *p++ = s[1]; break;
-			case 'Y': p += sprintf(p, "%04d", YearFromTime(t)); break;
-			case 'm': p += sprintf(p, "%02d", MonthFromTime(t) + 1); break;
-			case 'd': p += sprintf(p, "%02d", DateFromTime(t)); break;
-			case 'H': p += sprintf(p, "%02d", HourFromTime(t)); break;
-			case 'M': p += sprintf(p, "%02d", MinFromTime(t)); break;
-			case 'S': p += sprintf(p, "%02d", SecFromTime(t)); break;
-			case 'z':
-				if (tza < 0) {
-					tzsign = '-';
-					tza = -tza;
-				} else {
-					tzsign = '+';
-				}
-				tzhh = HourFromTime(tza);
-				tzmm = MinFromTime(tza);
-				if (tzmm != 0)
-					p += sprintf(p, "UTC%c%02d%02d", tzsign, tzhh, tzmm);
-				else if (tzhh != 0)
-					p += sprintf(p, "UTC%c%02d", tzsign, tzhh);
-				else
-					p += sprintf(p, "UTC");
-				break;
-			}
-			s += 2;
-		} else {
-			*p++ = *s++;
-		}
-	}
-	*p = 0;
+	int y = YearFromTime(t);
+	int m = MonthFromTime(t);
+	int d = DateFromTime(t);
+	sprintf(buf, "%04d-%02d-%02d", y, m+1, d);
+	return buf;
 }
 
-static const char *fmtlocal(char *buf, const char *fmt, double t)
+static char *fmttime(char *buf, double t, double tza)
 {
-	fmtdate(buf, fmt, LocalTime(t), LocalTZA());
+	int H = HourFromTime(t);
+	int M = MinFromTime(t);
+	int S = SecFromTime(t);
+	int ms = msFromTime(t);
+	int tzh = HourFromTime(fabs(tza));
+	int tzm = MinFromTime(fabs(tza));
+	if (tza == 0)
+		sprintf(buf, "%02d:%02d:%02d.%03dZ", H, M, S, ms);
+	else if (tza < 0)
+		sprintf(buf, "%02d:%02d:%02d.%03d-%02d%02d", H, M, S, ms, tzh, tzm);
+	else
+		sprintf(buf, "%02d:%02d:%02d.%03d+%02d%02d", H, M, S, ms, tzh, tzm);
 	return buf;
 }
 
-static const char *fmtutc(char *buf, const char *fmt, double t)
+static char *fmtdatetime(char *buf, double t, double tza)
 {
-	fmtdate(buf, fmt, t, 0);
+	char dbuf[20], tbuf[20];
+	fmtdate(dbuf, t);
+	fmttime(tbuf, t, tza);
+	sprintf(buf, "%sT%s", dbuf, tbuf);
 	return buf;
 }
 
@@ -419,7 +397,7 @@
 static void jsB_Date(js_State *J, unsigned int argc)
 {
 	char buf[64];
-	js_pushstring(J, fmtlocal(buf, FMT_DATETIME, Now()));
+	js_pushstring(J, fmtdatetime(buf, LocalTime(Now()), LocalTZA()));
 }
 
 static void jsB_new_Date(js_State *J, unsigned int argc)
@@ -466,7 +444,7 @@
 {
 	char buf[64];
 	double t = js_todate(J, 0);
-	js_pushstring(J, fmtlocal(buf, FMT_DATETIME, t));
+	js_pushstring(J, fmtdatetime(buf, LocalTime(t), LocalTZA()));
 }
 
 static void Dp_toDateString(js_State *J, unsigned int argc)
@@ -473,7 +451,7 @@
 {
 	char buf[64];
 	double t = js_todate(J, 0);
-	js_pushstring(J, fmtlocal(buf, FMT_DATE, t));
+	js_pushstring(J, fmtdate(buf, LocalTime(t)));
 }
 
 static void Dp_toTimeString(js_State *J, unsigned int argc)
@@ -480,7 +458,7 @@
 {
 	char buf[64];
 	double t = js_todate(J, 0);
-	js_pushstring(J, fmtlocal(buf, FMT_TIME, t));
+	js_pushstring(J, fmttime(buf, LocalTime(t), LocalTZA()));
 }
 
 static void Dp_toUTCString(js_State *J, unsigned int argc)
@@ -487,7 +465,7 @@
 {
 	char buf[64];
 	double t = js_todate(J, 0);
-	js_pushstring(J, fmtutc(buf, FMT_DATETIME, t));
+	js_pushstring(J, fmtdatetime(buf, t, 0));
 }
 
 static void Dp_toISOString(js_State *J, unsigned int argc)
@@ -494,7 +472,7 @@
 {
 	char buf[64];
 	double t = js_todate(J, 0);
-	js_pushstring(J, fmtutc(buf, FMT_DATETIME_ISO, t));
+	js_pushstring(J, fmtdatetime(buf, t, 0));
 }
 
 static void Dp_getFullYear(js_State *J, unsigned int argc)