diff --git a/src/plugin/customParseFormat/index.js b/src/plugin/customParseFormat/index.js index 771d13106..c7082833c 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 diff --git a/test/plugin/customParseFormat.test.js b/test/plugin/customParseFormat.test.js index a4588e976..fb4030176 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) +})