Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: UTC plugin set utcOffset value #668

Merged
merged 17 commits into from
Aug 27, 2019
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