From f6e7d2c38e6cccfb8d343c1503232a6c8764b57f Mon Sep 17 00:00:00 2001 From: Horst Schneider Date: Mon, 11 Feb 2019 10:45:37 +0100 Subject: [PATCH 1/3] Refactor parseDate (remove warnings and misleading comments, replace regex with string check). --- src/index.js | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/index.js b/src/index.js index f0f5fc1db..20a731c50 100644 --- a/src/index.js +++ b/src/index.js @@ -45,21 +45,17 @@ Utils.isDayjs = isDayjs Utils.wrapper = wrapper const parseDate = (date) => { - let reg - if (date === null) return new Date(NaN) // Treat null as an invalid date - if (Utils.isUndefined(date)) return new Date() + if (date === null) return new Date(NaN) // null is invalid + if (Utils.isUndefined(date)) return new Date() // today if (date instanceof Date) return date - // eslint-disable-next-line no-cond-assign - if ((typeof date === 'string') - && (/.*[^Z]$/i.test(date)) // looking for a better way - && (reg = date.match(C.REGEX_PARSE))) { - // 2018-08-08 or 20180808 - return new Date( - reg[1], reg[2] - 1, reg[3] || 1, - reg[4] || 0, reg[5] || 0, reg[6] || 0, reg[7] || 0 - ) + if (typeof date === 'string' && !date.toLowerCase().endsWith('z')) { + const d = date.match(C.REGEX_PARSE) + if (d) { + return new Date(d[1], d[2] - 1, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, d[7] || 0) + } } - return new Date(date) // timestamp + + return new Date(date) // everything else } class Dayjs { From 4fa7ddfa911411ff77177045703ca3ba69f41851 Mon Sep 17 00:00:00 2001 From: Horst Schneider Date: Mon, 11 Feb 2019 11:21:50 +0100 Subject: [PATCH 2/3] Add additional tests for invalid values, RFC 2822 and ECMAScript strings. --- test/parse.test.js | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/test/parse.test.js b/test/parse.test.js index 1204a0f91..e84a24417 100644 --- a/test/parse.test.js +++ b/test/parse.test.js @@ -15,7 +15,7 @@ describe('Parse', () => { expect(dayjs().valueOf()).toBe(moment().valueOf()) }) - it('String 20130208', () => { + it('moment-js like formatted dates', () => { global.console.warn = jest.genMockFunction()// moment.js '2018-4-1 1:1:1:22' will throw warn let d = '20130108' expect(dayjs(d).valueOf()).toBe(moment(d).valueOf()) @@ -46,6 +46,40 @@ describe('Parse', () => { expect(dayjs(time).valueOf()).toBe(moment(time).valueOf()) }) + it('String RFC 2822, time and zone', () => { + const time = 'Mon, 11 Feb 2019 09:46:50 GMT+1' + const expected = '2019-02-11T08:46:50.000Z' + const d = dayjs(time) + expect(d.toISOString()).toEqual(expected) + expect(d.valueOf()).toBe(moment(time).valueOf()) + }) + + it('String ECMAScript, time and zone', () => { + // should parse dates formatted in ECMA script format + // see https://www.ecma-international.org/ecma-262/9.0/index.html#sec-date.prototype.tostring + const time = 'Mon Feb 11 2019 11:01:37 GMT+0100 (Mitteleuropäische Normalzeit)' + const expected = '2019-02-11T10:01:37.000Z' + const d = dayjs(time) + expect(d.toISOString()).toEqual(expected) + expect(d.valueOf()).toBe(moment(time).valueOf()) + }) + + it('rejects invalid values', () => { + expect(dayjs({}).isValid()).toBe(false) + expect(dayjs(() => '2018-01-01').isValid()).toBe(false) + expect(dayjs(Infinity).isValid()).toBe(false) + expect(dayjs(NaN).isValid()).toBe(false) + expect(dayjs([2018, 5, 1, 13, 52, 44]).isValid()).toBe(false) // Arrays with time part + }) + + it('parses Arrays with date part', () => { + const dateParts = [2018, 5, 1] + const expected = '2018-05-01T00:00:00.000Z' + const d = dayjs(dateParts) + const normalized = d.add(d.utcOffset(), 'minutes') // make test run in every timezone + expect(normalized.toISOString()).toEqual(expected) + }) + it('String Other, Null and isValid', () => { global.console.warn = jest.genMockFunction()// moment.js otherString will throw warn expect(dayjs('otherString').toString().toLowerCase()).toBe(moment('otherString').toString().toLowerCase()) From 666998560908b75def0261bb7aceb112a7f47365 Mon Sep 17 00:00:00 2001 From: Horst Schneider Date: Wed, 13 Feb 2019 10:28:07 +0100 Subject: [PATCH 3/3] Revert to regex --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 20a731c50..fc89f357c 100644 --- a/src/index.js +++ b/src/index.js @@ -48,7 +48,7 @@ const parseDate = (date) => { if (date === null) return new Date(NaN) // null is invalid if (Utils.isUndefined(date)) return new Date() // today if (date instanceof Date) return date - if (typeof date === 'string' && !date.toLowerCase().endsWith('z')) { + if (typeof date === 'string' && !/Z$/i.test(date)) { const d = date.match(C.REGEX_PARSE) if (d) { return new Date(d[1], d[2] - 1, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, d[7] || 0)