Skip to content

Commit

Permalink
fix: UTC plugin set utcOffset value (#668)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamkun authored Aug 27, 2019
1 parent 4c862f6 commit 8877883
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 8 deletions.
9 changes: 5 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ const dayjs = (date, c, pl) => {
return new Dayjs(cfg) // eslint-disable-line no-use-before-define
}

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

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

const nextTimeStamp = this.valueOf() + (number * step)
const nextTimeStamp = this.$d.getTime() + (number * step)
return Utils.w(nextTimeStamp, this)
}

Expand Down Expand Up @@ -366,11 +367,11 @@ class Dayjs {
}

clone() {
return Utils.w(this.toDate(), this)
return Utils.w(this.$d, this)
}

toDate() {
return new Date(this.$d)
return new Date(this.valueOf())
}

toJSON() {
Expand Down
39 changes: 35 additions & 4 deletions src/plugin/utc/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { MILLISECONDS_A_MINUTE, MIN } from '../../constant'

export default (option, Dayjs, dayjs) => {
const localOffset = (new Date()).getTimezoneOffset()
const proto = Dayjs.prototype
dayjs.utc = function (date, format) {
const cfg = { date, utc: true, format }
Expand All @@ -18,6 +21,9 @@ export default (option, Dayjs, dayjs) => {
if (cfg.utc) {
this.$u = true
}
if (!this.$utils().u(cfg.$offset)) {
this.$offset = cfg.$offset
}
oldParse.call(this, cfg)
}

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

const oldUtcOffset = proto.utcOffset
proto.utcOffset = function () {
if (this.$u) {
return 0
proto.utcOffset = function (input) {
const { u } = this.$utils()
if (u(input)) {
if (this.$u) {
return 0
}
if (!u(this.$offset)) {
return this.$offset
}
return oldUtcOffset.call(this)
}
return oldUtcOffset.call(this)
const offset = Math.abs(input) <= 16 ? input * 60 : input
const newD = this.add(offset + (this.$u ? 0 : localOffset), MIN)
newD.$offset = offset
newD.$u = input === 0 // UTC mode
return newD
}

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

proto.valueOf = function () {
const addedOffset = !this.$utils().u(this.$offset)
? this.$offset + localOffset : 0
return this.$d.valueOf() - (addedOffset * MILLISECONDS_A_MINUTE)
}

proto.isUTC = function () {
return !!this.$u
}

proto.toISOString = function () {
return this.toDate().toISOString()
}

proto.toString = function () {
return this.toDate().toUTCString()
}
}
77 changes: 77 additions & 0 deletions test/plugin/utc-utcOffset.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import MockDate from 'mockdate'
import moment from 'moment'
import dayjs from '../../src'
import utc from '../../src/plugin/utc'

dayjs.extend(utc)

beforeEach(() => {
MockDate.set(new Date())
})

afterEach(() => {
MockDate.reset()
})

it('Set utcOffset -> Get utcOffset', () => {
expect(dayjs().utcOffset(540).utcOffset()).toBe(moment().utcOffset(540).utcOffset())
expect(dayjs().utcOffset(540).format()).toBe(moment().utcOffset(540).format())
expect(dayjs().utcOffset(60).format()).toBe(moment().utcOffset(60).format())
expect(dayjs().utcOffset(8).format()).toBe(moment().utcOffset(8).format())

expect(dayjs().utcOffset(-540).utcOffset()).toBe(moment().utcOffset(-540).utcOffset())
expect(dayjs().utcOffset(-540).format()).toBe(moment().utcOffset(-540).format())

expect(dayjs().utcOffset(-60).format()).toBe(moment().utcOffset(-60).format())
expect(dayjs().utcOffset(-8).format()).toBe(moment().utcOffset(-8).format())
})

it('valueOf, toDate, toString, toISOString should be the same as original', () => {
const d = dayjs()
const du = dayjs().utcOffset(9)
const mu = moment().utcOffset(9)
expect(d.valueOf()).toBe(du.valueOf())
expect(du.valueOf()).toBe(mu.valueOf())
expect(d.toDate()).toEqual(du.toDate())
expect(du.toDate()).toEqual(mu.toDate())
expect(du.toISOString()).toEqual(mu.toISOString())
expect(d.toString()).toEqual(d.toString())
})

it('clone', () => {
const du = dayjs().utcOffset(9)
const duClone = du.clone()
expect(du.valueOf()).toBe(duClone.valueOf())
expect(du.format()).toBe(duClone.format())
expect(du.utcOffset()).toBe(duClone.utcOffset())
})

it('immutable', () => {
const d = dayjs()
const du = d.utcOffset(9)
expect(d.utcOffset()).not.toBe(du.utcOffset())
expect(d.format()).not.toBe(du.format())
})

it('utcOffset(0) enable utc mode', () => {
expect(dayjs().utcOffset(0).format()).toBe(moment().utcOffset(0).format())
expect(dayjs().utcOffset(0).isUTC()).toBeTruthy()
})

test('UTC mode', () => {
const d = dayjs.utc('2000-01-01T06:00:00Z')
expect(d.isUTC()).toBeTruthy()
expect(d.utcOffset(0).isUTC()).toBeTruthy()
expect(d.utcOffset(1).isUTC()).toBeFalsy()
})

test('change hours when changing the utc offset in UTC mode', () => {
const d = dayjs.utc('2000-01-01T06:31:00Z')
expect(d.hour()).toBe(6)
expect(d.utcOffset(0).hour()).toBe(6)
expect(d.utcOffset(-60).hour()).toBe(5)
expect(d.utcOffset(60).hour()).toBe(7)
expect(d.utcOffset(-30).format('HH:mm')).toBe('06:01')
expect(d.utcOffset(30).format('HH:mm')).toBe('07:01')
expect(d.utcOffset(-1380).format('HH:mm')).toBe('07:31')
})
2 changes: 2 additions & 0 deletions types/plugin/utc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ declare module 'dayjs' {
local(): Dayjs

isUTC(): boolean

utcOffset(offset: number): Dayjs
}

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

0 comments on commit 8877883

Please sign in to comment.