From 112f42b26f7f2c0674ae87c854d16da216f4e15d Mon Sep 17 00:00:00 2001 From: iamkun Date: Wed, 21 Oct 2020 16:04:32 +0800 Subject: [PATCH] fix: update timezone plugin to support keepLocalTime fix #1149 --- src/plugin/timezone/index.js | 13 +++++++++---- test/plugin/timezone.test.js | 10 +++++++++- types/plugin/timezone.d.ts | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/plugin/timezone/index.js b/src/plugin/timezone/index.js index 3fe1bad07..06dd27c1f 100644 --- a/src/plugin/timezone/index.js +++ b/src/plugin/timezone/index.js @@ -1,3 +1,5 @@ +import { MIN, MS } from '../../constant' + const typeToPos = { year: 0, month: 1, @@ -7,8 +9,6 @@ const typeToPos = { second: 5 } -const ms = 'ms' - // Cache time-zone lookups from Intl.DateTimeFormat, // as it is a *very* slow method. const dtfCache = {} @@ -94,10 +94,15 @@ export default (o, c, d) => { const proto = c.prototype - proto.tz = function (timezone = defaultTimezone) { + proto.tz = function (timezone = defaultTimezone, keepLocalTime) { + const oldOffset = this.utcOffset() const target = this.toDate().toLocaleString('en-US', { timeZone: timezone }) const diff = Math.round((this.toDate() - new Date(target)) / 1000 / 60) - const ins = d(target).$set(ms, this.$ms).utcOffset(localUtcOffset - diff, true) + let ins = d(target).$set(MS, this.$ms).utcOffset(localUtcOffset - diff, true) + if (keepLocalTime) { + const newOffset = ins.utcOffset() + ins = ins.add(oldOffset - newOffset, MIN) + } ins.$x.$timezone = timezone return ins } diff --git a/test/plugin/timezone.test.js b/test/plugin/timezone.test.js index e9fb71f45..1f733baf6 100644 --- a/test/plugin/timezone.test.js +++ b/test/plugin/timezone.test.js @@ -1,8 +1,8 @@ import MockDate from 'mockdate' import moment from 'moment-timezone' import dayjs from '../../src' -import utc from '../../src/plugin/utc' import timezone from '../../src/plugin/timezone' +import utc from '../../src/plugin/utc' dayjs.extend(utc) dayjs.extend(timezone) @@ -260,6 +260,14 @@ describe('set Default', () => { }) }) +describe('keepLocalTime', () => { + const base = dayjs.tz('2013-11-18 11:55', 'America/Toronto') + it('keepLocalTime', () => { + expect(base.tz('Europe/Berlin').format()).toBe('2013-11-18T17:55:00+01:00') + expect(base.tz('Europe/Berlin', true).format()).toBe('2013-11-18T11:55:00+01:00') + }) +}) + describe('Get offsetName', () => { const dtz = dayjs.tz('2012-03-11 01:59:59', NY) it('short', () => { diff --git a/types/plugin/timezone.d.ts b/types/plugin/timezone.d.ts index 558558562..491f87465 100644 --- a/types/plugin/timezone.d.ts +++ b/types/plugin/timezone.d.ts @@ -5,7 +5,7 @@ export = plugin declare module 'dayjs' { interface Dayjs { - tz(timezone?: string): Dayjs + tz(timezone?: string, keepLocalTime?: boolean): Dayjs } interface DayjsTimezone {