Skip to content

Commit cbb755e

Browse files
authored
fix: update timezone plugin to support getting offset name e.g. EST (#1069)
* fix: update timezone plugin to support getting offset name e.g. EST * chore: typo
1 parent 3d73543 commit cbb755e

File tree

5 files changed

+56
-9
lines changed

5 files changed

+56
-9
lines changed

src/plugin/advancedFormat/index.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default (o, c, d) => { // locale needed later
1313
const locale = this.$locale()
1414
const utils = this.$utils()
1515
const str = formatStr || FORMAT_DEFAULT
16-
const result = str.replace(/\[([^\]]+)]|Q|wo|ww|w|gggg|Do|X|x|k{1,2}|S/g, (match) => {
16+
const result = str.replace(/\[([^\]]+)]|Q|wo|ww|w|zzz|z|gggg|Do|X|x|k{1,2}|S/g, (match) => {
1717
switch (match) {
1818
case 'Q':
1919
return Math.ceil((this.$M + 1) / 3)
@@ -33,6 +33,10 @@ export default (o, c, d) => { // locale needed later
3333
return Math.floor(this.$d.getTime() / 1000)
3434
case 'x':
3535
return this.$d.getTime()
36+
case 'z':
37+
return `[${this.offsetName()}]`
38+
case 'zzz':
39+
return `[${this.offsetName('long')}]`
3640
default:
3741
return match
3842
}

src/plugin/duration/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class Duration {
6060

6161
calMilliseconds() {
6262
this.$ms = Object.keys(this.$d).reduce((total, unit) => (
63-
total + ((this.$d[unit] || 0) * (unitToMS[unit] || 1))
63+
total + ((this.$d[unit] || 0) * (unitToMS[unit]))
6464
), 0)
6565
}
6666

@@ -106,7 +106,7 @@ class Duration {
106106
}
107107

108108
as(unit) {
109-
return this.$ms / (unitToMS[prettyUnit(unit)] || 1)
109+
return this.$ms / (unitToMS[prettyUnit(unit)])
110110
}
111111

112112
get(unit) {

src/plugin/timezone/index.js

+23-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ export default (o, c, d) => {
1313
let defaultTimezone
1414

1515
const localUtcOffset = d().utcOffset()
16-
const tzOffset = (timestamp, timezone) => {
16+
17+
const makeFormatParts = (timestamp, timezone, option = {}) => {
1718
const date = new Date(timestamp)
1819
const dtf = new Intl.DateTimeFormat('en-US', {
1920
hour12: false,
@@ -23,9 +24,14 @@ export default (o, c, d) => {
2324
day: '2-digit',
2425
hour: '2-digit',
2526
minute: '2-digit',
26-
second: '2-digit'
27+
second: '2-digit',
28+
timeZoneName: option.timeZoneName || 'short'
2729
})
28-
const formatResult = dtf.formatToParts(date)
30+
return dtf.formatToParts(date)
31+
}
32+
33+
const tzOffset = (timestamp, timezone) => {
34+
const formatResult = makeFormatParts(timestamp, timezone)
2935
const filled = []
3036
for (let i = 0; i < formatResult.length; i += 1) {
3137
const { type, value } = formatResult[i]
@@ -35,13 +41,14 @@ export default (o, c, d) => {
3541
filled[pos] = parseInt(value, 10)
3642
}
3743
}
44+
const hour = filled[3]
3845
// Workaround for the same behavior in different node version
3946
// https://github.com/nodejs/node/issues/33027
40-
const hour = filled[3]
47+
/* istanbul ignore next */
4148
const fixedHour = hour === 24 ? 0 : hour
4249
const utcString = `${filled[0]}-${filled[1]}-${filled[2]} ${fixedHour}:${filled[4]}:${filled[5]}:000`
4350
const utcTs = d.utc(utcString).valueOf()
44-
let asTS = +date
51+
let asTS = +timestamp
4552
const over = asTS % 1000
4653
asTS -= over
4754
return (utcTs - asTS) / (60 * 1000)
@@ -76,7 +83,16 @@ export default (o, c, d) => {
7683
proto.tz = function (timezone = defaultTimezone) {
7784
const target = this.toDate().toLocaleString('en-US', { timeZone: timezone })
7885
const diff = Math.round((this.toDate() - new Date(target)) / 1000 / 60)
79-
return d(target).utcOffset(localUtcOffset - diff, true).$set(ms, this.$ms)
86+
const ins = d(target).utcOffset(localUtcOffset - diff, true).$set(ms, this.$ms)
87+
ins.$x.$timezone = timezone
88+
return ins
89+
}
90+
91+
proto.offsetName = function (type) {
92+
// type: short(default) / long
93+
const zone = this.$x.$timezone || d.tz.guess()
94+
const result = makeFormatParts(this.valueOf(), zone, { timeZoneName: type }).find(m => m.type.toLowerCase() === 'timezonename')
95+
return result && result.value
8096
}
8197

8298
d.tz = function (input, timezone = defaultTimezone) {
@@ -89,6 +105,7 @@ export default (o, c, d) => {
89105
localTs = localTs || d.utc(input).valueOf()
90106
const [targetTs, targetOffset] = fixOffset(localTs, previousOffset, timezone)
91107
const ins = d(targetTs).utcOffset(targetOffset)
108+
ins.$x.$timezone = timezone
92109
return ins
93110
}
94111

test/plugin/advancedFormat.test.js

+12
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import dayjs from '../../src'
44
import advancedFormat from '../../src/plugin/advancedFormat'
55
import weekOfYear from '../../src/plugin/weekOfYear'
66
import weekYear from '../../src/plugin/weekYear'
7+
import timezone from '../../src/plugin/timezone'
8+
import utc from '../../src/plugin/utc'
79
import '../../src/locale/zh-cn'
810

11+
dayjs.extend(utc)
12+
dayjs.extend(timezone)
913
dayjs.extend(weekYear)
1014
dayjs.extend(weekOfYear)
1115
dayjs.extend(advancedFormat)
@@ -83,6 +87,14 @@ it('Format Week Year gggg', () => {
8387
expect(dayjs(d).format('gggg')).toBe(moment(d).format('gggg'))
8488
})
8589

90+
it('Format offsetName z zzz', () => {
91+
const dtz = dayjs.tz('2012-03-11 01:59:59', 'America/New_York')
92+
expect(dtz.format('z')).toBe('EST')
93+
expect(dtz.format('zzz')).toBe('Eastern Standard Time')
94+
expect(dayjs().format('z')).toBeDefined()
95+
expect(dayjs().format('zzz')).toBeDefined()
96+
})
97+
8698
it('Skips format strings inside brackets', () => {
8799
expect(dayjs().format('[Q]')).toBe('Q')
88100
expect(dayjs().format('[Do]')).toBe('Do')

test/plugin/timezone.test.js

+14
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,17 @@ describe('set Default', () => {
252252
expect(tokyo.valueOf()).toBe(1401591600000)
253253
})
254254
})
255+
256+
describe('Get offsetName', () => {
257+
const dtz = dayjs.tz('2012-03-11 01:59:59', NY)
258+
it('short', () => {
259+
const d = dtz.offsetName('short')
260+
const m = moment.tz('2012-03-11 01:59:59', NY).format('z')
261+
expect(d).toBe(m)
262+
expect(d).toBe('EST')
263+
})
264+
it('long', () => {
265+
const d = dtz.offsetName('long')
266+
expect(d).toBe('Eastern Standard Time')
267+
})
268+
})

0 commit comments

Comments
 (0)