diff --git a/package.json b/package.json index c76e01780..57f66b6fc 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "test": "TZ=Pacific/Auckland npm run test-tz && TZ=Europe/London npm run test-tz && TZ=America/Whitehorse npm run test-tz && npm run test-tz && jest", "test-tz": "date && jest test/timezone.test --coverage=false", - "lint": "./node_modules/.bin/eslint src/* test/* build/*", + "lint": "npx eslint src/* test/* build/*", "prettier": "prettier --write \"docs/**/*.md\"", "babel": "cross-env BABEL_ENV=build babel src --out-dir esm --copy-files && node build/esm", "build": "cross-env BABEL_ENV=build node build && npm run size", diff --git a/src/plugin/timezone/index.js b/src/plugin/timezone/index.js index 832fb4a73..4be414838 100644 --- a/src/plugin/timezone/index.js +++ b/src/plugin/timezone/index.js @@ -12,7 +12,7 @@ const typeToPos = { // Cache time-zone lookups from Intl.DateTimeFormat, // as it is a *very* slow method. const dtfCache = {} -const getDateTimeFormat = (timezone, options = {}) => { +const getDateTimeFormat = (timezone, options) => { const timeZoneName = options.timeZoneName || 'short' const key = `${timezone}|${timeZoneName}` let dtf = dtfCache[key] @@ -97,8 +97,13 @@ export default (o, c, d) => { const date = this.toDate() const target = date.toLocaleString('en-US', { timeZone: timezone }) const diff = Math.round((date - new Date(target)) / 1000 / 60) - let ins = d(target, { locale: this.$L }).$set(MS, this.$ms) - .utcOffset((-Math.round(date.getTimezoneOffset() / 15) * 15) - diff, true) + const offset = -date.getTimezoneOffset() - diff + if (offset === 0) { + return this.utc(keepLocalTime) + } + let ins = d(target) + .$set(MS, this.$ms) + .utcOffset(offset, true) if (keepLocalTime) { const newOffset = ins.utcOffset() ins = ins.add(oldOffset - newOffset, MIN) @@ -128,10 +133,13 @@ export default (o, c, d) => { d.tz = function (input, arg1, arg2) { const parseFormat = arg2 && arg1 const timezone = arg2 || arg1 || defaultTimezone - const previousOffset = tzOffset(+d(), timezone) - if (typeof input !== 'string') { - // timestamp number || js Date || Day.js - return d(input).tz(timezone) + const previousOffset = tzOffset(+d(input, parseFormat), timezone) + // To differentiate date only string (e.g. yy-mm-dd) from date string with negative + // 2-digit offset (hour offset zz, e.g. yy-mm-zz) we require at least 8 characters + // before offset (i.e. yy-mm-dd-zz) + if ((typeof input !== 'string') || /.{8,}[+-]\d\d:?(\d\d)?$|Z$/i.test(input)) { + // timestamp number || js Date || Day.js || input string with offset (e.g. -03:00) + return d(input, parseFormat).tz(timezone) } const localTs = d.utc(input, parseFormat).valueOf() const [targetTs, targetOffset] = fixOffset(localTs, previousOffset, timezone) diff --git a/src/plugin/utc/index.js b/src/plugin/utc/index.js index f1473570b..0379450d2 100644 --- a/src/plugin/utc/index.js +++ b/src/plugin/utc/index.js @@ -20,7 +20,6 @@ function offsetFromString(value = '') { return indicator === '+' ? totalOffsetInMinutes : -totalOffsetInMinutes } - export default (option, Dayjs, dayjs) => { const proto = Dayjs.prototype dayjs.utc = function (date) { diff --git a/test/issues/issue2027.correct-order.test.js b/test/issues/issue2027.correct-order.test.js deleted file mode 100644 index 3d9d6300c..000000000 --- a/test/issues/issue2027.correct-order.test.js +++ /dev/null @@ -1,78 +0,0 @@ -import MockDate from 'mockdate' -import dayjs from '../../src' -import duration from '../../src/plugin/duration' -import objectSupport from '../../src/plugin/objectSupport' - -dayjs.extend(objectSupport) -dayjs.extend(duration) - -beforeEach(() => { - MockDate.set(new Date()) -}) - -afterEach(() => { - MockDate.reset() -}) - -// issue 2027 -describe('issue 2027 - order objectSupport > Duration', () => { - it('add Duration object returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const durationToAdd = dayjs.duration(6, 'hours') - const testDate = baseDate.add(durationToAdd) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 20:01:02.003') - }) - it('subtract Duration object returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const durationToAdd = dayjs.duration(6, 'hours') - const testDate = baseDate.subtract(durationToAdd) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 08:01:02.003') - }) - - it('add number with unit returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const testDate = baseDate.add(6, 'hours') - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 20:01:02.003') - }) - it('subtract number with unit returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const testDate = baseDate.subtract(6, 'hours') - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 08:01:02.003') - }) - - it('parse string returns correct date', () => { - const testDate = dayjs('2022-06-26T14:01:02.003') - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 14:01:02.003') - }) - it('parse object returns correct date', () => { - const testDate = dayjs({ - year: '2022', - month: '05', - day: '26', - hour: '14', - minute: '01', - second: '02', - millisecond: '003' - }) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 14:01:02.003') - }) - - it('set hour with number returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const testDate = baseDate.hour(10) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 10:01:02.003') - }) - it('set hour with object returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const testDate = baseDate.set({ hour: '10' }) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 10:01:02.003') - }) -}) diff --git a/test/issues/issue2027.swapped-order.test.js b/test/issues/issue2027.swapped-order.test.js deleted file mode 100644 index 62a969e49..000000000 --- a/test/issues/issue2027.swapped-order.test.js +++ /dev/null @@ -1,79 +0,0 @@ -import MockDate from 'mockdate' -import dayjs from '../../src' -import duration from '../../src/plugin/duration' -import objectSupport from '../../src/plugin/objectSupport' - -dayjs.extend(duration) -dayjs.extend(objectSupport) - -beforeEach(() => { - MockDate.set(new Date()) -}) - -afterEach(() => { - MockDate.reset() -}) - -// issue 2027 -describe('issue 2027 - order objectSupport > Duration', () => { - it('add Duration object returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const durationToAdd = dayjs.duration(6, 'hours') - const testDate = baseDate.add(durationToAdd) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 20:01:02.003') - }) - - it('subtract Duration object returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const durationToAdd = dayjs.duration(6, 'hours') - const testDate = baseDate.subtract(durationToAdd) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 08:01:02.003') - }) - - it('add number with unit returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const testDate = baseDate.add(6, 'hours') - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 20:01:02.003') - }) - it('subtract number with unit returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const testDate = baseDate.subtract(6, 'hours') - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 08:01:02.003') - }) - - it('parse string returns correct date', () => { - const testDate = dayjs('2022-06-26T14:01:02.003') - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 14:01:02.003') - }) - it('parse object returns correct date', () => { - const testDate = dayjs({ - year: '2022', - month: '05', - day: '26', - hour: '14', - minute: '01', - second: '02', - millisecond: '003' - }) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 14:01:02.003') - }) - - it('set hour with number returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const testDate = baseDate.hour(10) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 10:01:02.003') - }) - it('set hour with object returns correct date', () => { - const baseDate = dayjs('2022-06-26T14:01:02.003') - const testDate = baseDate.set({ hour: '10' }) - - expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 10:01:02.003') - }) -}) diff --git a/test/issues/issue2037.gmt.test.js b/test/issues/issue2037.gmt.test.js new file mode 100644 index 000000000..8643d7508 --- /dev/null +++ b/test/issues/issue2037.gmt.test.js @@ -0,0 +1,272 @@ +import moment from 'moment-timezone' +import dayjs from '../../src' +import timezone from '../../src/plugin/timezone' +import utc from '../../src/plugin/utc' + +dayjs.extend(utc) +dayjs.extend(timezone) +dayjs.tz.setDefault('UTC') + +const ACR = 'Africa/Accra' +const VAN = 'America/Vancouver' +const LDN = 'Europe/London' + +function expectDayjsEqualsMoment(dayjsDate, momentDate) { + expect(dayjsDate.isValid()).toBe(momentDate.isValid()) + expect(dayjsDate.toISOString()).toBe(momentDate.toISOString()) + expect(dayjsDate.valueOf()).toBe(momentDate.valueOf()) + expect(Math.abs(dayjsDate.millisecond() - momentDate.millisecond())).toBeLessThanOrEqual(1) + expect(dayjsDate.toDate()).toEqual(momentDate.toDate()) + expect(dayjsDate.toJSON()).toEqual(momentDate.toJSON()) + expect(dayjsDate.format()).toBe(momentDate.format()) + expect(dayjsDate.utcOffset()).toBe(momentDate.utcOffset()) +} + +it('tz UTC of "0" should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC') + const momentDate = moment.tz(0, 'UTC') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('tz UTC of "0 + 0min" should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC').add(0, 'minutes') + const momentDate = moment.tz(0, 'UTC').add(0, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('tz UTC of "0 + 1min" should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC').add(1, 'minutes') + const momentDate = moment.tz(0, 'UTC').add(1, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:01:00Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz(0, "GMT") should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'GMT') + const momentDate = moment.tz(0, 'GMT') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz(0, "GMT") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'GMT').add(0, 'minutes') + const momentDate = moment.tz(0, 'GMT').add(0, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz(0, "GMT") with "+ 1min" should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'GMT').add(1, 'minutes') + const momentDate = moment.tz(0, 'GMT').add(1, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:01:00Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-01-22T10:21:32", "GMT") should return correct date', () => { + const dateString = '2023-01-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, 'GMT') + const momentDate = moment.tz(dateString, 'GMT') + + expect(dayjsDate.format()).toBe('2023-01-22T10:21:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-01-22T10:21:32", "GMT") with "+ 0min" should return correct date', () => { + const dateString = '2023-01-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, 'GMT').add(0, 'minutes') + const momentDate = moment.tz(dateString, 'GMT').add(0, 'minutes') + + expect(dayjsDate.format()).toBe('2023-01-22T10:21:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-01-22T10:21:32", "GMT") with "+ 1min" should return correct date', () => { + const dateString = '2023-01-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, 'GMT').add(1, 'minutes') + const momentDate = moment.tz(dateString, 'GMT').add(1, 'minutes') + + expect(dayjsDate.format()).toBe('2023-01-22T10:22:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +// GMT with DST +it('dayjs.tz("2023-06-22T10:21:32", "GMT") should return correct date', () => { + const dateString = '2023-06-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, 'GMT') + const momentDate = moment.tz(dateString, 'GMT') + + expect(dayjsDate.format()).toBe('2023-06-22T10:21:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-06-22T10:21:32", "GMT") with "+ 0min" should return correct date', () => { + const dateString = '2023-06-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, 'GMT').add(0, 'minutes') + const momentDate = moment.tz(dateString, 'GMT').add(0, 'minutes') + + expect(dayjsDate.format()).toBe('2023-06-22T10:21:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-06-22T10:21:32", "GMT") with "+ 1min" should return correct date', () => { + const dateString = '2023-06-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, 'GMT').add(1, 'minutes') + const momentDate = moment.tz(dateString, 'GMT').add(1, 'minutes') + + expect(dayjsDate.format()).toBe('2023-06-22T10:22:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-01-22T10:21:32", "Europe/London") should return correct date', () => { + const dateString = '2023-01-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, LDN) + const momentDate = moment.tz(dateString, LDN) + + expect(dayjsDate.format()).toBe('2023-01-22T10:21:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-01-22T10:21:32", "Europe/London") with "+ 0min" should return correct date', () => { + const dateString = '2023-01-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, LDN).add(0, 'minutes') + const momentDate = moment.tz(dateString, LDN).add(0, 'minutes') + + expect(dayjsDate.format()).toBe('2023-01-22T10:21:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-01-22T10:21:32", "Europe/London") with "+ 1min" should return correct date', () => { + const dateString = '2023-01-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, LDN).add(1, 'minutes') + const momentDate = moment.tz(dateString, LDN).add(1, 'minutes') + + expect(dayjsDate.format()).toBe('2023-01-22T10:22:32Z') + expect(dayjsDate.isUTC()).toBeTruthy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +// GMT with DST +it('dayjs.tz("2023-06-22T10:21:32", "Europe/London") should return correct date', () => { + const dateString = '2023-06-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, LDN) + const momentDate = moment.tz(dateString, LDN) + + expect(dayjsDate.format()).toBe('2023-06-22T10:21:32+01:00') + expect(dayjsDate.isUTC()).toBeFalsy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-06-22T10:21:32", "Europe/London") with "+ 0min" should return correct date', () => { + const dateString = '2023-06-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, LDN).add(0, 'minutes') + const momentDate = moment.tz(dateString, LDN).add(0, 'minutes') + + expect(dayjsDate.format()).toBe('2023-06-22T10:21:32+01:00') + expect(dayjsDate.isUTC()).toBeFalsy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +it('dayjs.tz("2023-06-22T10:21:32", "Europe/London") with "+ 1min" should return correct date', () => { + const dateString = '2023-06-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, LDN).add(1, 'minutes') + const momentDate = moment.tz(dateString, LDN).add(1, 'minutes') + + expect(dayjsDate.format()).toBe('2023-06-22T10:22:32+01:00') + expect(dayjsDate.isUTC()).toBeFalsy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +// CET without DST +it('dayjs.tz("2023-01-22T10:21:32", "CET") should return correct date', () => { + const dateString = '2023-01-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, 'CET') + const momentDate = moment.tz(dateString, 'CET') + + expect(dayjsDate.format()).toBe('2023-01-22T10:21:32+01:00') + expect(dayjsDate.isUTC()).toBeFalsy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +// CET with DST +it('dayjs.tz("2023-06-22T10:21:32", "CET") should return correct date', () => { + const dateString = '2023-06-22T10:21:32' + const dayjsDate = dayjs.tz(dateString, 'CET') + const momentDate = moment.tz(dateString, 'CET') + + expect(dayjsDate.format()).toBe('2023-06-22T10:21:32+02:00') + expect(dayjsDate.isUTC()).toBeFalsy() + expectDayjsEqualsMoment(dayjsDate, momentDate) +}) + +// offsetName and timezone name +it('should keep timezone name for "America/Vancouver" with "+ 0min"', () => { + const dateString = '2023-01-22T10:21:32' + const timeBefore = dayjs.tz(dateString, VAN) + const timezoneNameBefore = timeBefore.offsetName('long') + + expect(timezoneNameBefore).toBe('Pacific Standard Time') + expect(timeBefore.$x.$timezone).toBe('America/Vancouver') + + const momentDateAfter = moment.tz(dateString, VAN).add(0, 'minutes') + const timeAfter = timeBefore.add(0, 'minutes') + const timezoneNameAfter = timeAfter.offsetName('long') + + expect(timezoneNameAfter).toBe('Pacific Standard Time') + expect(timeAfter.$x.$timezone).toBe('America/Vancouver') + expectDayjsEqualsMoment(timeAfter, momentDateAfter) +}) + +it('should keep timezone name for "Africa/Accra" with "+ 0min"', () => { + const dateString = '2023-01-22T10:21:32' + const timeBefore = dayjs.tz(dateString, ACR) + const timezoneNameBefore = timeBefore.offsetName('long') + + expect(timezoneNameBefore).toBe('Greenwich Mean Time') + expect(timeBefore.$x.$timezone).toBe('Africa/Accra') + + const momentDateAfter = moment.tz(dateString, ACR).add(0, 'minutes') + const timeAfter = timeBefore.add(0, 'minutes') + const timezoneNameAfter = timeAfter.offsetName('long') + + expect(timezoneNameAfter).toBe('Greenwich Mean Time') + expect(timeAfter.$x.$timezone).toBe('Africa/Accra') + expectDayjsEqualsMoment(timeAfter, momentDateAfter) +}) + +it('should keep timezone name for "Africa/Accra" with "+ 1min"', () => { + const dateString = '2023-01-22T10:21:32' + const timeBefore = dayjs.tz(dateString, ACR) + const timezoneNameBefore = timeBefore.offsetName('long') + + expect(timezoneNameBefore).toBe('Greenwich Mean Time') + expect(timeBefore.$x.$timezone).toBe('Africa/Accra') + + const momentDateAfter = moment.tz(dateString, ACR).add(1, 'minutes') + const timeAfter = timeBefore.add(1, 'minutes') + const timezoneNameAfter = timeAfter.offsetName('long') + + expect(timezoneNameAfter).toBe('Greenwich Mean Time') + expect(timeAfter.$x.$timezone).toBe('Africa/Accra') + expectDayjsEqualsMoment(timeAfter, momentDateAfter) +}) diff --git a/test/plugin/timezone.test.js b/test/plugin/timezone.test.js index c4529c6c8..17c06fb3d 100644 --- a/test/plugin/timezone.test.js +++ b/test/plugin/timezone.test.js @@ -22,6 +22,19 @@ const VAN = 'America/Vancouver' const DEN = 'America/Denver' const TOKYO = 'Asia/Tokyo' const PARIS = 'Europe/Paris' +const UTC = 'UTC' +const GMT = 'GMT' + +function expectDayjsEqualsMoment(dayjsDate, momentDate) { + expect(dayjsDate.isValid()).toBe(momentDate.isValid()) + expect(dayjsDate.valueOf()).toBe(momentDate.valueOf()) + expect(dayjsDate.utcOffset()).toBe(momentDate.utcOffset()) + expect(Math.abs(dayjsDate.millisecond() - momentDate.millisecond())).toBeLessThanOrEqual(1) + expect(dayjsDate.toDate()).toEqual(momentDate.toDate()) + expect(dayjsDate.toJSON()).toEqual(momentDate.toJSON()) + expect(dayjsDate.toISOString()).toBe(momentDate.toISOString()) + expect(dayjsDate.format()).toBe(momentDate.format()) +} describe('Guess', () => { it('return string', () => { @@ -29,30 +42,124 @@ describe('Guess', () => { }) }) - describe('Parse', () => { - it('parse target time string', () => { + afterEach(() => { + dayjs.tz.setDefault() + moment.tz.setDefault() + }) + + it('parse target date string without timezone', () => { + dayjs.tz.setDefault(PARIS) + moment.tz.setDefault(PARIS) + + const d1 = dayjs.tz('2022-01-22') + const d1Added = dayjs.tz('2022-01-22').add(1, 'month') + const m1 = moment('2022-01-22') + const m1Added = moment('2022-01-22').add(1, 'month') + + expect(d1Added.format()).toBe('2022-02-22T00:00:00+01:00') + expectDayjsEqualsMoment(d1, m1) + expectDayjsEqualsMoment(d1Added, m1Added) + }) + + it('parse target date string with timezone LA', () => { + const d1 = dayjs.tz('2022-01-22', NY) + const d1Added = d1.add(1, 'month') + const m1 = moment.tz('2022-01-22', NY) + const m1Added = moment.tz('2022-01-22', NY).add(1, 'month') + + expect(d1Added.format()).toBe('2022-02-22T00:00:00-05:00') + expectDayjsEqualsMoment(d1, m1) + expectDayjsEqualsMoment(d1Added, m1Added) + }) + + it('parse target date string with timezone UTC', () => { + const d1 = dayjs.tz('2022-01-22', UTC) + const d1Added = d1.add(1, 'month') + const m1 = moment.tz('2022-01-22', UTC) + const m1Added = moment.tz('2022-01-22', UTC).add(1, 'month') + + expect(d1Added.format()).toBe('2022-02-22T00:00:00Z') + expectDayjsEqualsMoment(d1, m1) + expectDayjsEqualsMoment(d1Added, m1Added) + }) + + it('parse target date and time string without timezone', () => { + dayjs.tz.setDefault(PARIS) + moment.tz.setDefault(PARIS) + + const d1 = dayjs.tz('2022-01-22T13:24:35') + const d1Added = d1.add(1, 'month') + const m1 = moment('2022-01-22T13:24:35') + const m1Added = moment('2022-01-22T13:24:35').add(1, 'month') + + expect(d1.format()).toBe('2022-01-22T13:24:35+01:00') + expectDayjsEqualsMoment(d1, m1) + expect(d1Added.format()).toBe('2022-02-22T13:24:35+01:00') + expectDayjsEqualsMoment(d1Added, m1Added) + }) + + it('parse target date and time string with timezone NY', () => { const newYork = dayjs.tz('2014-06-01 12:00', NY) + const newYorkAdded = newYork.add(1, 'month') const MnewYork = moment.tz('2014-06-01 12:00', NY) + const MnewYorkAdded = moment.tz('2014-06-01 12:00', NY).add(1, 'month') + expect(newYork.format()).toBe('2014-06-01T12:00:00-04:00') + expect(newYork.utcOffset()).toBe(-240) + expect(newYork.valueOf()).toBe(1401638400000) + expectDayjsEqualsMoment(newYork, MnewYork) + expectDayjsEqualsMoment(newYorkAdded, MnewYorkAdded) + }) + + it('parse target date and time string with timezone UTC', () => { + const newYork = dayjs.tz('2022-01-22T14:15:16', UTC) + const newYorkAdded = newYork.add(1, 'month') + const MnewYork = moment.tz('2022-01-22T14:15:16', UTC) + const MnewYorkAdded = moment.tz('2022-01-22T14:15:16', UTC).add(1, 'month') + + expect(newYork.format()).toBe('2022-01-22T14:15:16Z') + expect(newYork.utcOffset()).toBe(0) + expect(newYork.valueOf()).toBe(1642860916000) + expectDayjsEqualsMoment(newYork, MnewYork) + expectDayjsEqualsMoment(newYorkAdded, MnewYorkAdded) + }) + + it('parse target date and time string with offset and timezone', () => { + const newYork = dayjs.tz('2014-06-01 12:00:03+03:00', NY) + const MnewYork = moment.tz('2014-06-01 12:00:03+03:00', NY) + expect(newYork.format()).toBe('2014-06-01T05:00:03-04:00') expect(newYork.format()).toBe(MnewYork.format()) expect(newYork.utcOffset()).toBe(-240) expect(newYork.utcOffset()).toBe(MnewYork.utcOffset()) - expect(newYork.valueOf()).toBe(1401638400000) + expect(newYork.valueOf()).toBe(1401613203000) expect(newYork.valueOf()).toBe(MnewYork.valueOf()) }) - it('parse timestamp, js Date, Day.js object', () => { + it('parse timestamp (js Date)', () => { const d = new Date('2020-08-07T12:00-07:00') const result = '2020-08-07T12:00:00-07:00' const TjsDate = dayjs.tz(d, VAN) - const Tdayjs = dayjs.tz(dayjs(d), VAN) - const Timestamp = dayjs.tz(d.getTime(), VAN) - const Tmoment = moment.tz(d, VAN) + const TjsDateMoment = moment.tz(d, VAN) + expect(TjsDate.format()).toBe(result) - expect(Tdayjs.format()).toBe(result) + expect(TjsDate.format()).toBe(TjsDateMoment.format()) + }) + + it('parse timestamp (js Date.getTime)', () => { + const d = new Date('2020-08-07T12:00-07:00') + const result = '2020-08-07T12:00:00-07:00' + + const Timestamp = dayjs.tz(d.getTime(), VAN) expect(Timestamp.format()).toBe(result) - expect(Tmoment.format()).toBe(result) + }) + + it('parse timestamp (Day.js object)', () => { + const d = new Date('2020-08-07T12:00-07:00') + const result = '2020-08-07T12:00:00-07:00' + + const Tdayjs = dayjs.tz(dayjs(d), VAN) + expect(Tdayjs.format()).toBe(result) }) it('parse and convert between timezones', () => { @@ -82,7 +189,7 @@ describe('Convert', () => { expect(losAngeles.utcOffset()).toBe(MlosAngeles.utcOffset()) }) - it('convert to target time', () => { + it('convert to target time (dayjs vs. moment)', () => { [dayjs, moment].forEach((_) => { const losAngeles = _('2014-06-01T12:00:00Z').tz('America/Los_Angeles') expect(losAngeles.format()).toBe('2014-06-01T05:00:00-07:00') @@ -122,7 +229,6 @@ describe('Convert', () => { }) }) - describe('DST, a time that never existed Spring Forward', () => { // 11 March 2012, 02:00:00 clocks were // turned forward 1 hour to 11 March 2012, 03:00:00 local @@ -179,15 +285,6 @@ describe('DST, a time that never existed Spring Forward', () => { describe('DST, a time that never existed Fall Back', () => { // In the fall, at the end of DST - it('2012-11-04 00:59:59', () => { - const s = '2012-11-04 00:59:59'; - [dayjs, moment].forEach((_) => { - const d = _.tz(s, NY) - expect(d.format()).toBe('2012-11-04T00:59:59-04:00') - expect(d.utcOffset()).toBe(-240) - expect(d.valueOf()).toBe(1352005199000) - }) - }) it('2012-11-04 00:59:59', () => { const s = '2012-11-04 00:59:59'; [dayjs, moment].forEach((_) => { @@ -296,7 +393,7 @@ describe('Get offsetName', () => { }) }) -describe('CustomPraseFormat', () => { +describe('CustomParseFormat', () => { const result = 1602786600 it('normal', () => { expect(dayjs.tz('2020/10/15 12:30', DEN).unix()).toBe(result) @@ -330,3 +427,449 @@ describe('startOf and endOf', () => { expect(tzWithLocality.startOf('week').format('YYYY-MM-DD')).toEqual('2023-02-15') }) }) +describe('set default timezone', () => { + beforeEach(() => { + MockDate.set(new Date()) + }) + + afterEach(() => { + MockDate.reset() + dayjs.tz.setDefault() + moment.tz.setDefault() + }) + + it('with "NYC" - dayjs("2022-12-03T20:14:43") should return correct date', () => { + dayjs.tz.setDefault(NY) + moment.tz.setDefault(NY) + + const dateValue = '2022-12-03T20:14:43' + const dayjsDate = dayjs.tz(dateValue) + const momentDate = moment(dateValue) + + expect(dayjsDate.format()).toBe('2022-12-03T20:14:43-05:00') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('with "NYC" - dayjs(0) should return correct date', () => { + dayjs.tz.setDefault(NY) + moment.tz.setDefault(NY) + + const dateValue = 0 + const dayjsDate = dayjs.tz(dateValue) + const momentDate = moment(dateValue) + + expect(dayjsDate.format()).toBe('1969-12-31T19:00:00-05:00') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('with "UTC" - dayjs(0) should return correct date', () => { + dayjs.tz.setDefault(UTC) + moment.tz.setDefault(UTC) + + const dateValue = 0 + const dayjsDate = dayjs.tz(dateValue) + const momentDate = moment(dateValue) + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('with "UTC" - dayjs(0).add(0, "minutes") should return correct date', () => { + dayjs.tz.setDefault('UTC') + moment.tz.setDefault('UTC') + + const dateValue = 0 + const dayjsDate = dayjs.tz(dateValue).add(0, 'minutes') + const momentDate = moment(dateValue).add(0, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) +}) + +describe('issue 2037 about parse with "add"', () => { + it('tz(0, "UTC") should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC') + const momentDate = moment.tz(0, 'UTC') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('tz(60000, "UTC") should return correct date', () => { + const dayjsDate = dayjs.tz(60000, 'UTC') + const momentDate = moment.tz(60000, 'UTC') + + expect(dayjsDate.format()).toBe('1970-01-01T00:01:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs.tz("1970-01-01T00:00:00" ,"UTC") should return same value as moment', () => { + const dateValue = '1970-01-01T00:00:00' + const tz = UTC + const dayjsDate = dayjs.tz(dateValue, tz) + const momentDate = moment.tz(dateValue, tz) + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('tz(0, "UTC").add(0, "minutes") should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC').add(0, 'minutes') + const momentDate = moment.tz(0, 'UTC').add(0, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('tz(0, "UTC").add(1, "minutes") should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC').add(1, 'minutes') + const momentDate = moment.tz(0, 'UTC').add(1, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:01:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs.tz("1970-01-01T00:00:00" ,"UTC") with "+ 0min" should return correct date', () => { + const dateValue = '1970-01-01T00:00:00' + const tz = UTC + const dayjsDateAdded = dayjs.tz(dateValue, tz).add(0, 'minutes') + const momentDateAdded = moment.tz(dateValue, tz).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDateAdded, momentDateAdded) + }) + + it('dayjs(0).tz("UTC") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs(0).tz(UTC).add(0, 'minutes') + const momentDate = moment(0).tz(UTC).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs(60000).tz("UTC") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs(60000).tz(UTC).add(0, 'minutes') + const momentDate = moment(60000).tz(UTC).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + // Another timezone with offset '0' + it('dayjs(0).tz("GMT", true) of "+ 0min" should return correct date', () => { + const keepLocalTime = true + const dayjsDate = dayjs(0).tz(GMT, keepLocalTime).add(0, 'minutes') + const momentDate = moment(0).tz(GMT, keepLocalTime).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs.tz(0, "America/New_York") with "+ 0min" should return correct date', () => { + const dateValue = 0 + const dayjsDateAdded = dayjs.tz(dateValue, NY).add(0, 'minutes') + const momentDateAdded = moment.tz(dateValue, NY).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDateAdded, momentDateAdded) + }) + + it('dayjs.tz("1970-01-01T00:00:00" ,"America/New_York") with "+ 0min" should return correct date', () => { + const dateValue = '1970-01-01T00:00:00' + const dayjsDateAdded = dayjs.tz(dateValue, NY).add(0, 'minutes') + const momentDateAdded = moment.tz(dateValue, NY).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDateAdded, momentDateAdded) + }) +}) + +describe('issue 2037 about convert with "add"', () => { + it('dayjs(0).tz("UTC") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs(0).tz(UTC).add(0, 'minutes') + const momentDate = moment.tz(0, UTC).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs(0).tz("America/New_York") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs(0).tz(NY).add(0, 'minutes') + const momentDate = moment.tz(0, NY).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs(60000).tz("UTC") with "+ 0min" should return correct date', () => { + const dateValue = 60000 + const dayjsDate = dayjs(dateValue).tz(UTC).add(0, 'minutes') + const momentDate = moment.tz(dateValue, UTC).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs(60000).tz("America/New_York") with "+ 0min" should return correct date', () => { + const dateValue = 60000 + const dayjsDate = dayjs(dateValue).tz(NY).add(0, 'minutes') + const momentDate = moment.tz(dateValue, NY).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) +}) + +describe('issue 1860 - setting month in UTC timezone', () => { + beforeEach(() => { + MockDate.set(new Date()) + dayjs.tz.setDefault('CDT') + moment.tz.setDefault('CDT') + }) + + afterEach(() => { + MockDate.reset() + }) + + it('setting month using timezone "America/Godthab" should return correct date', () => { + const dateValue = '2022-04-19T03:00:00-02:00' + const tz = 'America/Godthab' + const dayjsDate = dayjs(dateValue).tz(tz) + const dayjsDateWithMonth = dayjs(dayjsDate).month(3) + const momentDate = moment(dateValue).tz(tz) + const momentDateWithMonth = moment(dateValue).tz(tz).month(3) + + expect(dayjsDateWithMonth.format()).toBe('2022-04-19T03:00:00-02:00') + expectDayjsEqualsMoment(dayjsDate, momentDate) + expectDayjsEqualsMoment(dayjsDateWithMonth, momentDateWithMonth) + }) + + it('setting month using timezone "GMT" should return correct date', () => { + const dateValue = '2022-04-19T03:00:00-02:00' + const tz = GMT + const dayjsDate = dayjs(dateValue).tz(tz) + const dayjsDateUTC = dayjs(dayjsDate).tz(GMT) + const dayjsDateUTCWithMonth = dayjs(dayjsDateUTC).month(3) + const momentDate = moment(dateValue).tz(tz) + const momentDateUTC = moment(moment(dateValue).tz(tz)).tz(GMT) + const momentDateUTCWithMonth = moment(moment(dateValue).tz(tz)).tz(GMT).month(3) + + expect(dayjsDateUTCWithMonth.format()).toBe('2022-04-19T05:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + expectDayjsEqualsMoment(dayjsDateUTC, momentDateUTC) + expectDayjsEqualsMoment(dayjsDateUTCWithMonth, momentDateUTCWithMonth) + }) +}) +describe('set default timezone', () => { + beforeEach(() => { + MockDate.set(new Date()) + }) + + afterEach(() => { + MockDate.reset() + dayjs.tz.setDefault() + moment.tz.setDefault() + }) + + it('with "NYC" - dayjs("2022-12-03T20:14:43") should return correct date', () => { + dayjs.tz.setDefault(NY) + moment.tz.setDefault(NY) + + const dateValue = '2022-12-03T20:14:43' + const dayjsDate = dayjs.tz(dateValue) + const momentDate = moment(dateValue) + + expect(dayjsDate.format()).toBe('2022-12-03T20:14:43-05:00') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('with "NYC" - dayjs(0) should return correct date', () => { + dayjs.tz.setDefault(NY) + moment.tz.setDefault(NY) + + const dateValue = 0 + const dayjsDate = dayjs.tz(dateValue) + const momentDate = moment(dateValue) + + expect(dayjsDate.format()).toBe('1969-12-31T19:00:00-05:00') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('with "UTC" - dayjs(0) should return correct date', () => { + dayjs.tz.setDefault(UTC) + moment.tz.setDefault(UTC) + + const dateValue = 0 + const dayjsDate = dayjs.tz(dateValue) + const momentDate = moment(dateValue) + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('with "UTC" - dayjs(0).add(0, "minutes") should return correct date', () => { + dayjs.tz.setDefault('UTC') + moment.tz.setDefault('UTC') + + const dateValue = 0 + const dayjsDate = dayjs.tz(dateValue).add(0, 'minutes') + const momentDate = moment(dateValue).add(0, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) +}) + +describe('issue 2037 about parse with "add"', () => { + it('tz(0, "UTC") should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC') + const momentDate = moment.tz(0, 'UTC') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('tz(60000, "UTC") should return correct date', () => { + const dayjsDate = dayjs.tz(60000, 'UTC') + const momentDate = moment.tz(60000, 'UTC') + + expect(dayjsDate.format()).toBe('1970-01-01T00:01:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs.tz("1970-01-01T00:00:00" ,"UTC") should return same value as moment', () => { + const dateValue = '1970-01-01T00:00:00' + const tz = UTC + const dayjsDate = dayjs.tz(dateValue, tz) + const momentDate = moment.tz(dateValue, tz) + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('tz(0, "UTC").add(0, "minutes") should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC').add(0, 'minutes') + const momentDate = moment.tz(0, 'UTC').add(0, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('tz(0, "UTC").add(1, "minutes") should return correct date', () => { + const dayjsDate = dayjs.tz(0, 'UTC').add(1, 'minutes') + const momentDate = moment.tz(0, 'UTC').add(1, 'minutes') + + expect(dayjsDate.format()).toBe('1970-01-01T00:01:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs.tz("1970-01-01T00:00:00" ,"UTC") with "+ 0min" should return correct date', () => { + const dateValue = '1970-01-01T00:00:00' + const tz = UTC + const dayjsDateAdded = dayjs.tz(dateValue, tz).add(0, 'minutes') + const momentDateAdded = moment.tz(dateValue, tz).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDateAdded, momentDateAdded) + }) + + it('dayjs(0).tz("UTC") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs(0).tz(UTC).add(0, 'minutes') + const momentDate = moment(0).tz(UTC).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs(60000).tz("UTC") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs(60000).tz(UTC).add(0, 'minutes') + const momentDate = moment(60000).tz(UTC).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + // Another timezone with offset '0' + it('dayjs(0).tz("GMT", true) of "+ 0min" should return correct date', () => { + const keepLocalTime = true + const dayjsDate = dayjs(0).tz(GMT, keepLocalTime).add(0, 'minutes') + const momentDate = moment(0).tz(GMT, keepLocalTime).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs.tz(0, "America/New_York") with "+ 0min" should return correct date', () => { + const dateValue = 0 + const dayjsDateAdded = dayjs.tz(dateValue, NY).add(0, 'minutes') + const momentDateAdded = moment.tz(dateValue, NY).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDateAdded, momentDateAdded) + }) + + it('dayjs.tz("1970-01-01T00:00:00" ,"America/New_York") with "+ 0min" should return correct date', () => { + const dateValue = '1970-01-01T00:00:00' + const dayjsDateAdded = dayjs.tz(dateValue, NY).add(0, 'minutes') + const momentDateAdded = moment.tz(dateValue, NY).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDateAdded, momentDateAdded) + }) +}) + +describe('issue 2037 about convert with "add"', () => { + it('dayjs(0).tz("UTC") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs(0).tz(UTC).add(0, 'minutes') + const momentDate = moment.tz(0, UTC).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs(0).tz("America/New_York") with "+ 0min" should return correct date', () => { + const dayjsDate = dayjs(0).tz(NY).add(0, 'minutes') + const momentDate = moment.tz(0, NY).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs(60000).tz("UTC") with "+ 0min" should return correct date', () => { + const dateValue = 60000 + const dayjsDate = dayjs(dateValue).tz(UTC).add(0, 'minutes') + const momentDate = moment.tz(dateValue, UTC).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) + + it('dayjs(60000).tz("America/New_York") with "+ 0min" should return correct date', () => { + const dateValue = 60000 + const dayjsDate = dayjs(dateValue).tz(NY).add(0, 'minutes') + const momentDate = moment.tz(dateValue, NY).add(0, 'minutes') + + expectDayjsEqualsMoment(dayjsDate, momentDate) + }) +}) + +describe('issue 1860 - setting month in UTC timezone', () => { + beforeEach(() => { + MockDate.set(new Date()) + dayjs.tz.setDefault('CDT') + moment.tz.setDefault('CDT') + }) + + afterEach(() => { + MockDate.reset() + }) + + it('setting month using timezone "America/Godthab" should return correct date', () => { + const dateValue = '2022-04-19T03:00:00-02:00' + const tz = 'America/Godthab' + const dayjsDate = dayjs(dateValue).tz(tz) + const dayjsDateWithMonth = dayjs(dayjsDate).month(3) + const momentDate = moment(dateValue).tz(tz) + const momentDateWithMonth = moment(dateValue).tz(tz).month(3) + + expect(dayjsDateWithMonth.format()).toBe('2022-04-19T03:00:00-02:00') + expectDayjsEqualsMoment(dayjsDate, momentDate) + expectDayjsEqualsMoment(dayjsDateWithMonth, momentDateWithMonth) + }) + + it('setting month using timezone "GMT" should return correct date', () => { + const dateValue = '2022-04-19T03:00:00-02:00' + const tz = GMT + const dayjsDate = dayjs(dateValue).tz(tz) + const dayjsDateUTC = dayjs(dayjsDate).tz(GMT) + const dayjsDateUTCWithMonth = dayjs(dayjsDateUTC).month(3) + const momentDate = moment(dateValue).tz(tz) + const momentDateUTC = moment(moment(dateValue).tz(tz)).tz(GMT) + const momentDateUTCWithMonth = moment(moment(dateValue).tz(tz)).tz(GMT).month(3) + + expect(dayjsDateUTCWithMonth.format()).toBe('2022-04-19T05:00:00Z') + expectDayjsEqualsMoment(dayjsDate, momentDate) + expectDayjsEqualsMoment(dayjsDateUTC, momentDateUTC) + expectDayjsEqualsMoment(dayjsDateUTCWithMonth, momentDateUTCWithMonth) + }) +}) diff --git a/test/plugin/updateLocale.test.js b/test/plugin/updateLocale.test.js index 1fdfe93cb..04202337a 100644 --- a/test/plugin/updateLocale.test.js +++ b/test/plugin/updateLocale.test.js @@ -70,6 +70,7 @@ describe('Update locale', () => { }) it('Update invalid date string', () => { + const warn = jest.spyOn(console, 'warn').mockImplementation(() => {}) const locale = 'en' const localeSetting = { invalidDate: 'bad date' } dayjs.updateLocale(locale, localeSetting) @@ -78,5 +79,6 @@ describe('Update locale', () => { moment.locale(locale) expect(dayjs('').format()).toBe(moment('').format()) expect(dayjs('otherString').format()).toBe(moment('otherString').format()) + warn.mockReset() }) })