Repository: iamkun/dayjs
Pull request #2693 (2024-07-18 12:27:57)

fix: timezone plugin currect parse UTC tz
fix https://github.com/iamkun/dayjs/issues/2248


Patch:
diff --git a/src/index.js b/src/index.js
index f28d649..061ade1 100644
--- a/src/index.js
+++ b/src/index.js
@@ -50,7 +50,7 @@ const dayjs = function (date, c) {
 const wrapper = (date, instance) =>
   dayjs(date, {
     locale: instance.$L,
-    utc: instance.$offset !== 0 && instance.$u,
+    utc: instance.$u,
     x: instance.$x,
     $offset: instance.$offset // todo: refactor; do not use this.$offset in you code
   })
diff --git a/src/plugin/timezone/index.js b/src/plugin/timezone/index.js
index 832fb4a..bcacf9a 100644
--- a/src/plugin/timezone/index.js
+++ b/src/plugin/timezone/index.js
@@ -97,11 +97,18 @@ export default (o, c, d) => {
     const date = this.toDate()
     const target = date.toLocaleString('en-US', { timeZone: timezone })
     const diff = Math.round((date - new Date(target)) / 1000 / 60)
-    let ins = d(target, { locale: this.$L }).$set(MS, this.$ms)
-      .utcOffset((-Math.round(date.getTimezoneOffset() / 15) * 15) - diff, true)
-    if (keepLocalTime) {
-      const newOffset = ins.utcOffset()
-      ins = ins.add(oldOffset - newOffset, MIN)
+    const offset = (-Math.round(date.getTimezoneOffset() / 15) * 15) - diff
+    const isUTC = !Number(offset)
+    let ins
+    if (isUTC) { // if utcOffset is 0, turn it to UTC mode
+      ins = this.utcOffset(0, keepLocalTime)
+    } else {
+      ins = d(target, { locale: this.$L }).$set(MS, this.$ms)
+        .utcOffset(offset, true)
+      if (keepLocalTime) {
+        const newOffset = ins.utcOffset()
+        ins = ins.add(oldOffset - newOffset, MIN)
+      }
     }
     ins.$x.$timezone = timezone
     return ins


Test patch:
diff --git a/test/plugin/timezone.test.js b/test/plugin/timezone.test.js
index c4529c6..d83a03f 100644
--- a/test/plugin/timezone.test.js
+++ b/test/plugin/timezone.test.js
@@ -330,3 +330,25 @@ describe('startOf and endOf', () => {
     expect(tzWithLocality.startOf('week').format('YYYY-MM-DD')).toEqual('2023-02-15')
   })
 })
+
+
+describe('UTC timezone', () => {
+  it('TZ with UTC with Locale', () => {
+    const test1 = dayjs('2000-01-01T09:00:00+09:00').tz('Asia/Seoul').locale('en')
+    expect(test1.hour()).toBe(9)
+    const test2 = dayjs('2000-01-01T09:00:00+09:00').tz('Asia/Hong_Kong').locale('en')
+    expect(test2.hour()).toBe(8)
+    const test3 = dayjs('2000-01-01T09:00:00+09:00').tz('Etc/UTC').locale('en')
+    expect(test3.hour()).toBe(0)
+  })
+
+  it('TZ with UTC', () => {
+    const dayjs1 = dayjs('2000-01-01T09:01:00+09:00').tz('Etc/UTC', false)
+    expect(dayjs1.format()).toBe('2000-01-01T00:01:00Z')
+    const moment1 = moment('2000-01-01T09:01:00+09:00').tz('Etc/UTC', false)
+    expect(moment1.format()).toBe('2000-01-01T00:01:00Z')
+    const dayjs2 = dayjs('2000-01-01T09:01:00+09:00').tz('Etc/UTC', true)
+    const moment2 = moment('2000-01-01T09:01:00+09:00').tz('Etc/UTC', true)
+    expect(dayjs2.format()).toBe(moment2.format())
+  })
+})
diff --git a/test/timezone.test.js b/test/timezone.test.js
index 9d61fe0..aea31fd 100644
--- a/test/timezone.test.js
+++ b/test/timezone.test.js
@@ -81,12 +81,3 @@ it('UTC diff in DST', () => {
   expect(day1.diff(day2, 'd'))
     .toBe(-3)
 })
-
-it('TZ with Locale', () => {
-  const test1 = dayjs('2000-01-01T09:00:00+09:00').tz('Asia/Seoul').locale('en')
-  expect(test1.hour()).toBe(9)
-  const test2 = dayjs('2000-01-01T09:00:00+09:00').tz('Asia/Hong_Kong').locale('en')
-  expect(test2.hour()).toBe(8)
-  const test3 = dayjs('2000-01-01T09:00:00+09:00').tz('Etc/UTC').locale('en')
-  expect(test3.hour()).toBe(0)
-})