Skip to content

Commit 8877883

Browse files
authored
fix: UTC plugin set utcOffset value (#668)
1 parent 4c862f6 commit 8877883

File tree

4 files changed

+119
-8
lines changed

4 files changed

+119
-8
lines changed

src/index.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ const dayjs = (date, c, pl) => {
3838
return new Dayjs(cfg) // eslint-disable-line no-use-before-define
3939
}
4040

41-
const wrapper = (date, instance) => dayjs(date, { locale: instance.$L, utc: instance.$u })
41+
const wrapper = (date, instance) =>
42+
dayjs(date, { locale: instance.$L, utc: instance.$u, $offset: instance.$offset })
4243

4344
const Utils = U // for plugin use
4445
Utils.l = parseLocale
@@ -263,7 +264,7 @@ class Dayjs {
263264
[C.S]: C.MILLISECONDS_A_SECOND
264265
}[unit] || 1 // ms
265266

266-
const nextTimeStamp = this.valueOf() + (number * step)
267+
const nextTimeStamp = this.$d.getTime() + (number * step)
267268
return Utils.w(nextTimeStamp, this)
268269
}
269270

@@ -366,11 +367,11 @@ class Dayjs {
366367
}
367368

368369
clone() {
369-
return Utils.w(this.toDate(), this)
370+
return Utils.w(this.$d, this)
370371
}
371372

372373
toDate() {
373-
return new Date(this.$d)
374+
return new Date(this.valueOf())
374375
}
375376

376377
toJSON() {

src/plugin/utc/index.js

+35-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
import { MILLISECONDS_A_MINUTE, MIN } from '../../constant'
2+
13
export default (option, Dayjs, dayjs) => {
4+
const localOffset = (new Date()).getTimezoneOffset()
25
const proto = Dayjs.prototype
36
dayjs.utc = function (date, format) {
47
const cfg = { date, utc: true, format }
@@ -18,6 +21,9 @@ export default (option, Dayjs, dayjs) => {
1821
if (cfg.utc) {
1922
this.$u = true
2023
}
24+
if (!this.$utils().u(cfg.$offset)) {
25+
this.$offset = cfg.$offset
26+
}
2127
oldParse.call(this, cfg)
2228
}
2329

@@ -39,11 +45,22 @@ export default (option, Dayjs, dayjs) => {
3945
}
4046

4147
const oldUtcOffset = proto.utcOffset
42-
proto.utcOffset = function () {
43-
if (this.$u) {
44-
return 0
48+
proto.utcOffset = function (input) {
49+
const { u } = this.$utils()
50+
if (u(input)) {
51+
if (this.$u) {
52+
return 0
53+
}
54+
if (!u(this.$offset)) {
55+
return this.$offset
56+
}
57+
return oldUtcOffset.call(this)
4558
}
46-
return oldUtcOffset.call(this)
59+
const offset = Math.abs(input) <= 16 ? input * 60 : input
60+
const newD = this.add(offset + (this.$u ? 0 : localOffset), MIN)
61+
newD.$offset = offset
62+
newD.$u = input === 0 // UTC mode
63+
return newD
4764
}
4865

4966
const oldFormat = proto.format
@@ -53,7 +70,21 @@ export default (option, Dayjs, dayjs) => {
5370
return oldFormat.call(this, str)
5471
}
5572

73+
proto.valueOf = function () {
74+
const addedOffset = !this.$utils().u(this.$offset)
75+
? this.$offset + localOffset : 0
76+
return this.$d.valueOf() - (addedOffset * MILLISECONDS_A_MINUTE)
77+
}
78+
5679
proto.isUTC = function () {
5780
return !!this.$u
5881
}
82+
83+
proto.toISOString = function () {
84+
return this.toDate().toISOString()
85+
}
86+
87+
proto.toString = function () {
88+
return this.toDate().toUTCString()
89+
}
5990
}

test/plugin/utc-utcOffset.test.js

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import MockDate from 'mockdate'
2+
import moment from 'moment'
3+
import dayjs from '../../src'
4+
import utc from '../../src/plugin/utc'
5+
6+
dayjs.extend(utc)
7+
8+
beforeEach(() => {
9+
MockDate.set(new Date())
10+
})
11+
12+
afterEach(() => {
13+
MockDate.reset()
14+
})
15+
16+
it('Set utcOffset -> Get utcOffset', () => {
17+
expect(dayjs().utcOffset(540).utcOffset()).toBe(moment().utcOffset(540).utcOffset())
18+
expect(dayjs().utcOffset(540).format()).toBe(moment().utcOffset(540).format())
19+
expect(dayjs().utcOffset(60).format()).toBe(moment().utcOffset(60).format())
20+
expect(dayjs().utcOffset(8).format()).toBe(moment().utcOffset(8).format())
21+
22+
expect(dayjs().utcOffset(-540).utcOffset()).toBe(moment().utcOffset(-540).utcOffset())
23+
expect(dayjs().utcOffset(-540).format()).toBe(moment().utcOffset(-540).format())
24+
25+
expect(dayjs().utcOffset(-60).format()).toBe(moment().utcOffset(-60).format())
26+
expect(dayjs().utcOffset(-8).format()).toBe(moment().utcOffset(-8).format())
27+
})
28+
29+
it('valueOf, toDate, toString, toISOString should be the same as original', () => {
30+
const d = dayjs()
31+
const du = dayjs().utcOffset(9)
32+
const mu = moment().utcOffset(9)
33+
expect(d.valueOf()).toBe(du.valueOf())
34+
expect(du.valueOf()).toBe(mu.valueOf())
35+
expect(d.toDate()).toEqual(du.toDate())
36+
expect(du.toDate()).toEqual(mu.toDate())
37+
expect(du.toISOString()).toEqual(mu.toISOString())
38+
expect(d.toString()).toEqual(d.toString())
39+
})
40+
41+
it('clone', () => {
42+
const du = dayjs().utcOffset(9)
43+
const duClone = du.clone()
44+
expect(du.valueOf()).toBe(duClone.valueOf())
45+
expect(du.format()).toBe(duClone.format())
46+
expect(du.utcOffset()).toBe(duClone.utcOffset())
47+
})
48+
49+
it('immutable', () => {
50+
const d = dayjs()
51+
const du = d.utcOffset(9)
52+
expect(d.utcOffset()).not.toBe(du.utcOffset())
53+
expect(d.format()).not.toBe(du.format())
54+
})
55+
56+
it('utcOffset(0) enable utc mode', () => {
57+
expect(dayjs().utcOffset(0).format()).toBe(moment().utcOffset(0).format())
58+
expect(dayjs().utcOffset(0).isUTC()).toBeTruthy()
59+
})
60+
61+
test('UTC mode', () => {
62+
const d = dayjs.utc('2000-01-01T06:00:00Z')
63+
expect(d.isUTC()).toBeTruthy()
64+
expect(d.utcOffset(0).isUTC()).toBeTruthy()
65+
expect(d.utcOffset(1).isUTC()).toBeFalsy()
66+
})
67+
68+
test('change hours when changing the utc offset in UTC mode', () => {
69+
const d = dayjs.utc('2000-01-01T06:31:00Z')
70+
expect(d.hour()).toBe(6)
71+
expect(d.utcOffset(0).hour()).toBe(6)
72+
expect(d.utcOffset(-60).hour()).toBe(5)
73+
expect(d.utcOffset(60).hour()).toBe(7)
74+
expect(d.utcOffset(-30).format('HH:mm')).toBe('06:01')
75+
expect(d.utcOffset(30).format('HH:mm')).toBe('07:01')
76+
expect(d.utcOffset(-1380).format('HH:mm')).toBe('07:31')
77+
})

types/plugin/utc.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ declare module 'dayjs' {
1111
local(): Dayjs
1212

1313
isUTC(): boolean
14+
15+
utcOffset(offset: number): Dayjs
1416
}
1517

1618
export function utc(config?: ConfigType, format?: string): Dayjs

0 commit comments

Comments
 (0)