Repository: iamkun/dayjs
Pull request #2713 (2024-08-20 14:55:52)

D2M


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a594fd..5b16f3b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,7 @@
 * add UTC support to negativeYear plugin ([#2692](https://github.com/iamkun/dayjs/issues/2692)) ([f3ef705](https://github.com/iamkun/dayjs/commit/f3ef705613af83333fe132b470896a65e12f31b0))
 * Fix zero offset issue when use tz with locale ([#2532](https://github.com/iamkun/dayjs/issues/2532)) ([d0e6738](https://github.com/iamkun/dayjs/commit/d0e6738a66e1b65d3706aad2f9168ebb43d4f887))
 * Improve typing for min/max plugin ([#2573](https://github.com/iamkun/dayjs/issues/2573)) ([4fbe94a](https://github.com/iamkun/dayjs/commit/4fbe94aaba8c815a42cf4d23dabac918ec50e68c))
-* timezone plugin currect parse UTC tz ([#2693](https://github.com/iamkun/dayjs/issues/2693)) ([b575c81](https://github.com/iamkun/dayjs/commit/b575c81a8c9c85c7a0baf6f608a12f9d3ba95bd1))
+* timezone plugin correct parse UTC tz ([#2693](https://github.com/iamkun/dayjs/issues/2693)) ([b575c81](https://github.com/iamkun/dayjs/commit/b575c81a8c9c85c7a0baf6f608a12f9d3ba95bd1))
 
 ## [1.11.11](https://github.com/iamkun/dayjs/compare/v1.11.10...v1.11.11) (2024-04-28)
 
diff --git a/README.md b/README.md
index 74d8805..9247b6e 100644
--- a/README.md
+++ b/README.md
@@ -127,6 +127,10 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
   <img width="70" src="https://images.opencollective.com/chudovo/3c866f5/logo/256.png?height=256">
 </a>
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+<a href="https://www.honrev.com" target="_blank">
+  <img width="70" src="https://github.com/user-attachments/assets/b3203350-34c1-4637-b8b1-d9b8bab346d3">
+</a>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 <a href="https://github.com/alan-eu" target="_blank">
   <img width="70" src="https://avatars.githubusercontent.com/u/18175329?s=52&v=4">
 </a>
@@ -142,6 +146,10 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
 <a href="https://bestkru.com/" target="_blank">
   <img width="70" src="https://avatars.githubusercontent.com/u/159320286" alt="BestKru">
 </a>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+<a href="https://route4me.com/" target="_blank">
+  <img width="70" src="https://github.com/user-attachments/assets/3fbc86c5-98a9-49c2-beae-1969026fcd76" alt="Route Optimizer and Route Planner Software">
+</a>
 
 
 ## Contributors
diff --git a/docs/demo/index.js b/docs/demo/index.js
index 4299e30..7c6951e 100644
--- a/docs/demo/index.js
+++ b/docs/demo/index.js
@@ -7,3 +7,6 @@ dayjs('2018-08-08').format()
 
 // format
 dayjs().format('YYYY-MM-DD')
+
+// locale
+dayjs().locale('zh-cn').format()
diff --git a/src/plugin/customParseFormat/index.js b/src/plugin/customParseFormat/index.js
index 771d131..c708283 100644
--- a/src/plugin/customParseFormat/index.js
+++ b/src/plugin/customParseFormat/index.js
@@ -1,6 +1,6 @@
 import { u } from '../localizedFormat/utils'
 
-const formattingTokens = /(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g
+const formattingTokens = /(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g
 
 const match1 = /\d/ // 0 - 9
 const match2 = /\d\d/ // 00 - 99
@@ -66,6 +66,9 @@ const expressions = {
   a: [matchWord, function (input) {
     this.afternoon = meridiemMatch(input, true)
   }],
+  Q: [match1, function (input) {
+    this.month = ((input - 1) * 3) + 1
+  }],
   S: [match1, function (input) {
     this.milliseconds = +input * 100
   }],
@@ -95,6 +98,8 @@ const expressions = {
       }
     }
   }],
+  w: [match1to2, addInput('week')],
+  ww: [match2, addInput('week')],
   M: [match1to2, addInput('month')],
   MM: [match2, addInput('month')],
   MMM: [matchWord, function (input) {
@@ -173,12 +178,12 @@ function makeParser(format) {
   }
 }
 
-const parseFormattedInput = (input, format, utc) => {
+const parseFormattedInput = (input, format, utc, dayjs) => {
   try {
     if (['x', 'X'].indexOf(format) > -1) return new Date((format === 'X' ? 1000 : 1) * input)
     const parser = makeParser(format)
     const {
-      year, month, day, hours, minutes, seconds, milliseconds, zone
+      year, month, day, hours, minutes, seconds, milliseconds, zone, week
     } = parser(input)
     const now = new Date()
     const d = day || ((!year && !month) ? now.getDate() : 1)
@@ -197,7 +202,12 @@ const parseFormattedInput = (input, format, utc) => {
     if (utc) {
       return new Date(Date.UTC(y, M, d, h, m, s, ms))
     }
-    return new Date(y, M, d, h, m, s, ms)
+    let newDate
+    newDate = new Date(y, M, d, h, m, s, ms)
+    if (week) {
+      newDate = dayjs(newDate).week(week).toDate()
+    }
+    return newDate
   } catch (e) {
     return new Date('') // Invalid Date
   }
@@ -224,12 +234,12 @@ export default (o, C, d) => {
       const isStrictWithLocale = args[3] === true
       const isStrict = isStrictWithoutLocale || isStrictWithLocale
       let pl = args[2]
-      if (isStrictWithLocale) [,, pl] = args
+      if (isStrictWithLocale) [, , pl] = args
       locale = this.$locale()
       if (!isStrictWithoutLocale && pl) {
         locale = d.Ls[pl]
       }
-      this.$d = parseFormattedInput(date, format, utc)
+      this.$d = parseFormattedInput(date, format, utc, d)
       this.init()
       if (pl && pl !== true) this.$L = this.locale(pl).$L
       // use != to treat


Test patch:
diff --git a/test/plugin/customParseFormat.test.js b/test/plugin/customParseFormat.test.js
index a4588e9..fb40301 100644
--- a/test/plugin/customParseFormat.test.js
+++ b/test/plugin/customParseFormat.test.js
@@ -7,9 +7,11 @@ import '../../src/locale/zh-cn'
 import customParseFormat from '../../src/plugin/customParseFormat'
 import advancedFormat from '../../src/plugin/advancedFormat'
 import localizedFormats from '../../src/plugin/localizedFormat'
+import weekOfYear from '../../src/plugin/weekOfYear'
 
 dayjs.extend(customParseFormat)
 dayjs.extend(localizedFormats)
+dayjs.extend(weekOfYear) // test parse w, ww
 
 beforeEach(() => {
   MockDate.set(new Date())
@@ -437,3 +439,24 @@ it('parse X x', () => {
   dayjs.extend(advancedFormat)
   expect(dayjs(input2, format2, true).valueOf()).toBe(moment(input2, format2, true).valueOf())
 })
+
+it('parse Q, [Q]', () => {
+  const input1 = '2024-Q1'
+  const input2 = '2024-Q2'
+  const input3 = '2024-Q3'
+  const input4 = '2024-Q4'
+  const format = 'YYYY-[Q]Q'
+  expect(dayjs(input1, format).valueOf()).toBe(moment(input1, format).valueOf())
+  expect(dayjs(input2, format).valueOf()).toBe(moment(input2, format).valueOf())
+  expect(dayjs(input3, format).valueOf()).toBe(moment(input3, format).valueOf())
+  expect(dayjs(input4, format).valueOf()).toBe(moment(input4, format).valueOf())
+})
+
+it('parse w, ww', () => {
+  const input = '2024-w1'
+  const format1 = 'YYYY-[w]w'
+  expect(dayjs(input, format1).format(format1)).toBe(input)
+  const input2 = '2024-w32'
+  const format2 = 'YYYY-[w]ww'
+  expect(dayjs(input2, format2).format(format1)).toBe(input2)
+})