From 33631473ab0fe01e34b428ede874f9754a942e3e Mon Sep 17 00:00:00 2001 From: Matthew Strasiotto <39424834+matthewstrasiotto@users.noreply.github.com> Date: Mon, 5 Oct 2020 18:52:14 +1100 Subject: [PATCH] fix(util.convert): epoch times stored as strings convert correctly, unit test fixup, parse iso dates in local tz (#699) * fix: parse string dates directly with moment * fix: error for convert unknown to moment more specific Previously stated "Unable to convert to Date" Now states "Unable to convert to moment" * test: add html doc for testing offset behaviour * test: test string to date conversions more rigorously * refactor(utils.convert): remove repeated code, throw TypeErrors Previously, "Date" & "Moment" had identical switch branches, but each return statement in "Date" had `moment(...).toDate()`. Now, Date branch is just `convert(object, "Moment").toDate()`. Also, each now throw TypeErrors, & Date branch catches "TypeError" & rethrows its own. * test(util.convert): test for "TypeError" when testing throws * test(util.convert): more robust output checking for date conversion * fix(util.convert): convert epoch times in strings to number before converting to moment * test(util.convert): improve "testOffset" example * Delete testOffset.html as per review comment Co-authored-by: Yotam Berkowitz --- lib/util.js | 40 ++++++++++++++++++--------------------- test/util-convert.test.js | 35 +++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/lib/util.js b/lib/util.js index 36363534b1..40e6f7bdca 100644 --- a/lib/util.js +++ b/lib/util.js @@ -11,7 +11,7 @@ import moment from "moment"; // for example '/Date(1198908717056)/' or '/Date(1198908717056-0700)/' // code from http://momentjs.com/ const ASPDateRegex = /^\/?Date\((-?\d+)/i; - +const NumericRegex = /^\d+$/; /** * Convert an object into another type * @@ -59,26 +59,17 @@ export function convert(object, type) { return String(object); case "Date": - if (isNumber(object)) { - return new Date(object); + try { + return convert(object, "Moment").toDate(); } - if (object instanceof Date) { - return new Date(object.valueOf()); - } else if (moment.isMoment(object)) { - return new Date(object.valueOf()); - } - if (isString(object)) { - match = ASPDateRegex.exec(object); - if (match) { - // object is an ASP date - return new Date(Number(match[1])); // parse number + catch(e){ + if (e instanceof TypeError) { + throw new TypeError( + "Cannot convert object of type " + getType(object) + " to type " + type + ); } else { - return moment(new Date(object)).toDate(); // parse string + throw e; } - } else { - throw new Error( - "Cannot convert object of type " + getType(object) + " to type Date" - ); } case "Moment": @@ -95,12 +86,17 @@ export function convert(object, type) { if (match) { // object is an ASP date return moment(Number(match[1])); // parse number - } else { - return moment(object); // parse string + } + match = NumericRegex.exec(object); + + if (match) { + return moment(Number(object)); } + + return moment(object); // parse string } else { - throw new Error( - "Cannot convert object of type " + getType(object) + " to type Date" + throw new TypeError( + "Cannot convert object of type " + getType(object) + " to type " + type ); } diff --git a/test/util-convert.test.js b/test/util-convert.test.js index b0a33ed6b4..3328b67b8a 100644 --- a/test/util-convert.test.js +++ b/test/util-convert.test.js @@ -42,11 +42,36 @@ describe("util", function() { }); it("converts to Date from Number", function() { - assert(util.convert(1198908717056, "Date") instanceof Date); + const d1 = util.convert(1198908717056, "Date"); + assert(d1 instanceof Date); + assert(!isNaN(d1.valueOf())); }); - it("converts to Date from String", function() { - assert(util.convert("1198908717056", "Date") instanceof Date); + it("converts to Date from epoch int stored as String", function() { + const d1 = util.convert("1198908717056", "Date"); + assert(d1 instanceof Date); + assert(!isNaN(d1.valueOf())); + }); + + it("converting epoch int stored as String === epoch int stored as int", + function() { + const d1 = util.convert("1198908717056", "Date"); + const d2 = util.convert(1198908717056, "Date"); + assert.strictEqual(d1.valueOf(), d2.valueOf()); + } + ); + + it("converts ISO dates to midnight in local TZ", function() { + const dateISO = util.convert("2020-04-20", "Date"); + const dttmISO = util.convert("2020-04-20T00:00:00", "Date"); + + assert(dateISO instanceof Date); + assert(dttmISO instanceof Date); + + assert(!isNaN(dateISO.valueOf())); + assert(!isNaN(dttmISO.valueOf())); + + assert.strictEqual(dateISO.valueOf(),dttmISO.valueOf()); }); it("converts to Date from Moment", function() { @@ -58,7 +83,7 @@ describe("util", function() { function() { util.convert({}, "Date"); }, - Error, + TypeError, null ); }); @@ -86,7 +111,7 @@ describe("util", function() { function() { util.convert({}, "Moment"); }, - Error, + TypeError, null ); });