diff --git a/src/plugin/utc/index.js b/src/plugin/utc/index.js index b5b5f4e6..8f840590 100644 --- a/src/plugin/utc/index.js +++ b/src/plugin/utc/index.js @@ -1,5 +1,26 @@ import { MILLISECONDS_A_MINUTE, MIN } from '../../constant' +export const REGEX_VALID_OFFSET_FORMAT = /[+-]\d\d(?::?\d\d)?/g +export const REGEX_OFFSET_HOURS_MINUTES_FORMAT = /([+-]|\d\d)/g + +function offsetFromString(value = '') { + const offset = value.match(REGEX_VALID_OFFSET_FORMAT) + + if (!offset) { + return null + } + + const [indicator, hoursOffset, minutesOffset] = `${offset[0]}`.match(REGEX_OFFSET_HOURS_MINUTES_FORMAT) || ['-', 0, 0] + const totalOffsetInMinutes = (+hoursOffset * 60) + (+minutesOffset) + + if (totalOffsetInMinutes === 0) { + return 0 + } + + return indicator === '+' ? totalOffsetInMinutes : -totalOffsetInMinutes +} + + export default (option, Dayjs, dayjs) => { const proto = Dayjs.prototype dayjs.utc = function (date) { @@ -59,6 +80,12 @@ export default (option, Dayjs, dayjs) => { } return oldUtcOffset.call(this) } + if (typeof input === 'string') { + input = offsetFromString(input) + if (input === null) { + return this + } + } const offset = Math.abs(input) <= 16 ? input * 60 : input let ins = this if (keepLocalTime) { diff --git a/test/plugin/utc.test.js b/test/plugin/utc.test.js index 888412a8..2dd5c0c3 100644 --- a/test/plugin/utc.test.js +++ b/test/plugin/utc.test.js @@ -226,6 +226,71 @@ describe('UTC Offset', () => { expect(dayjs().utcOffset()).toBe(moment().utcOffset()) expect(dayjs().utc().utcOffset()).toBe(moment().utc().utcOffset()) }) + + it('get utc offset with a number value', () => { + const time = '2021-02-28 19:40:10' + const hoursOffset = -8 + const daysJS = dayjs(time).utc().utcOffset(hoursOffset * 60, true) + const momentJS = moment(time).utc(true).utcOffset(hoursOffset, true) + + expect(daysJS.toISOString()).toEqual(momentJS.toISOString()) + expect(daysJS.utcOffset()).toEqual(hoursOffset * 60) + expect(daysJS.utcOffset()).toEqual(momentJS.utcOffset()) + }) + + it('get utc offset with a negative valid string value, format: HH:mm', () => { + const time = '2021-02-28 19:40:10' + const hoursOffset = -8 + const daysJS = dayjs(time).utc().utcOffset(`-0${Math.abs(hoursOffset)}:00`, true) + const momentJS = moment(time).utc(true).utcOffset(`-0${Math.abs(hoursOffset)}:00`, true) + + expect(daysJS.toISOString()).toEqual(momentJS.toISOString()) + expect(daysJS.utcOffset()).toEqual(hoursOffset * 60) + expect(daysJS.utcOffset()).toEqual(momentJS.utcOffset()) + }) + + it('get utc offset with a positive valid string value, format: HH:mm', () => { + const time = '2021-02-28 19:40:10' + const hoursOffset = 8 + const daysJS = dayjs(time).utc().utcOffset(`+0${hoursOffset}:00`, true) + const momentJS = moment(time).utc(true).utcOffset(`+0${hoursOffset}:00`, true) + + expect(daysJS.toISOString()).toEqual(momentJS.toISOString()) + expect(daysJS.utcOffset()).toEqual(hoursOffset * 60) + expect(daysJS.utcOffset()).toEqual(momentJS.utcOffset()) + }) + + it('get utc offset with a negative valid string value, format: HHmm', () => { + const time = '2021-02-28 19:40:10' + const hoursOffset = -8 + const daysJS = dayjs(time).utc().utcOffset(`-0${Math.abs(hoursOffset)}00`, true) + const momentJS = moment(time).utc(true).utcOffset(`-0${Math.abs(hoursOffset)}00`, true) + + expect(daysJS.toISOString()).toEqual(momentJS.toISOString()) + expect(daysJS.utcOffset()).toEqual(hoursOffset * 60) + expect(daysJS.utcOffset()).toEqual(momentJS.utcOffset()) + }) + + it('get utc offset with a positive valid string value, format: HHmm', () => { + const time = '2021-02-28 19:40:10' + const hoursOffset = 8 + const daysJS = dayjs(time).utc().utcOffset(`+0${hoursOffset}00`, true) + const momentJS = moment(time).utc(true).utcOffset(`+0${hoursOffset}00`, true) + + expect(daysJS.toISOString()).toEqual(momentJS.toISOString()) + expect(daysJS.utcOffset()).toEqual(hoursOffset * 60) + expect(daysJS.utcOffset()).toEqual(momentJS.utcOffset()) + }) + + it('get utc offset with an invalid string value, value: random', () => { + const time = '2021-02-28 19:40:10' + const daysJS = dayjs(time, { utc: true }).utc(true).utcOffset('random') + const momentJS = moment(time).utc(true).utcOffset('random') + + expect(daysJS.toISOString()).toEqual(momentJS.toISOString()) + expect(daysJS.utcOffset()).toEqual(0) + expect(daysJS.utcOffset()).toEqual(momentJS.utcOffset()) + }) }) describe('Diff', () => {