From 1d3bf80a5c8128f597837c684ea3e9e3d0e73804 Mon Sep 17 00:00:00 2001
From: Anil Anar <anilanar@hotmail.com>
Date: Tue, 4 Apr 2017 23:41:47 +0200
Subject: [PATCH] fix date/instant construction for years 0 <= y < 100

---
 src/Data/Date.js             | 16 ++++++++++++----
 src/Data/DateTime/Instant.js | 10 +++++++++-
 test/Test/Main.purs          | 14 ++++++++++++++
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/src/Data/Date.js b/src/Data/Date.js
index a1b5669..03f5842 100644
--- a/src/Data/Date.js
+++ b/src/Data/Date.js
@@ -1,16 +1,24 @@
 "use strict";
 
+var createDate = function (y, m, d) {
+  var date = new Date(Date.UTC(y, m, d));
+  if (y >= 0 && y < 100) {
+    date.setUTCFullYear(y);
+  }
+  return date;
+}
+
 exports.canonicalDateImpl = function (ctor, y, m, d) {
-  var date = new Date(Date.UTC(y, m - 1, d));
+  var date = createDate(y, m - 1, d);
   return ctor(date.getUTCFullYear())(date.getUTCMonth() + 1)(date.getUTCDate());
 };
 
 exports.calcWeekday = function (y, m, d) {
-  return new Date(Date.UTC(y, m - 1, d)).getUTCDay();
+  return createDate(y, m - 1, d).getUTCDay();
 };
 
 exports.calcDiff = function (y1, m1, d1, y2, m2, d2) {
-  var dt1 = new Date(Date.UTC(y1, m1 - 1, d1));
-  var dt2 = new Date(Date.UTC(y2, m2 - 1, d2));
+  var dt1 = createDate(y1, m1 - 1, d1);
+  var dt2 = createDate(y2, m2 - 1, d2);
   return dt1.getTime() - dt2.getTime();
 };
diff --git a/src/Data/DateTime/Instant.js b/src/Data/DateTime/Instant.js
index e79b5e2..e43a121 100644
--- a/src/Data/DateTime/Instant.js
+++ b/src/Data/DateTime/Instant.js
@@ -1,7 +1,15 @@
 "use strict";
 
+var createDateTime = function (y, m, d, h, mi, s, ms) {
+  var dateTime = new Date(Date.UTC(y, m, d, h, mi, s, ms));
+  if (y >= 0 && y < 100) {
+    dateTime.setUTCFullYear(y);
+  }
+  return dateTime;
+}
+
 exports.fromDateTimeImpl = function (y, mo, d, h, mi, s, ms) {
-  return new Date(Date.UTC(y, mo - 1, d, h, mi, s, ms)).getTime();
+  return createDateTime(y, mo - 1, d, h, mi, s, ms).getTime();
 };
 
 exports.toDateTimeImpl = function (ctor) {
diff --git a/test/Test/Main.purs b/test/Test/Main.purs
index 1d55817..8bb528e 100644
--- a/test/Test/Main.purs
+++ b/test/Test/Main.purs
@@ -25,6 +25,12 @@ type Tests = Eff (console :: CONSOLE, assert :: ASSERT) Unit
 main :: Tests
 main = do
 
+  let epochDate = unsafePartial fromJust $ Date.canonicalDate
+                  <$> toEnum 1
+                  <*> pure bottom
+                  <*> pure bottom
+  let epochDateTime = DateTime.DateTime epochDate bottom
+  let epochMillis = -62135596800000.0
   -- time --------------------------------------------------------------------
 
   log "Check that Hour is a good BoundedEnum"
@@ -105,6 +111,11 @@ main = do
   assert $ not $ Date.isLeapYear (unsafeYear 2017)
   assert $ Date.isLeapYear (unsafeYear 2016)
 
+  log "Check that epoch is correctly constructed"
+  assert $ Just (Date.year epochDate) == toEnum 1
+  assert $ Date.month epochDate == bottom
+  assert $ Date.day epochDate == bottom
+
   -- datetime ----------------------------------------------------------------
 
   let dt1 = DateTime.DateTime d1 t1
@@ -134,6 +145,9 @@ main = do
   let topInstant = Instant.fromDateTime top
   assert $ Just topInstant == Instant.instant (Instant.unInstant topInstant)
 
+  log "Check that an Instant can be constructed from epoch"
+  assert $ (Instant.unInstant $ Instant.fromDateTime epochDateTime) == Duration.Milliseconds epochMillis
+
   log "Check that instant/datetime conversion is bijective"
   assert $ Instant.toDateTime (Instant.fromDateTime bottom) == bottom
   assert $ Instant.toDateTime (Instant.fromDateTime top) == top