Skip to content

Commit 79eafa5

Browse files
authored
fix(format): resolve formatDate replacements overlapping
* Fix formatDate replacements overlapping * Change REGEX_FORMAT to prevent matching yyy format * Add DateUtils test to check whether formatting rules do not overlap
1 parent ce89bfc commit 79eafa5

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

src/utils/DateUtils.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,22 @@ const utils = {
203203
const year = this.getFullYear(date)
204204
const month = this.getMonth(date) + 1
205205
const day = this.getDate(date)
206-
return formatStr
207-
.replace(/dd/, (`0${day}`).slice(-2))
208-
.replace(/d/, day)
209-
.replace(/yyyy/, year)
210-
.replace(/yy/, String(year).slice(2))
211-
.replace(/MMMM/, this.getMonthName(this.getMonth(date), translationTemp.months))
212-
.replace(/MMM/, this.getMonthNameAbbr(this.getMonth(date), translationTemp.monthsAbbr))
213-
.replace(/MM/, (`0${month}`).slice(-2))
214-
.replace(/M(?![aäe])/, month)
215-
.replace(/o/, this.getNthSuffix(this.getDate(date)))
216-
.replace(/E(?![eéi])/, this.getDayNameAbbr(date, translationTemp.days))
206+
207+
const matches = {
208+
dd: (`0${day}`).slice(-2),
209+
d: day,
210+
yyyy: year,
211+
yy: String(year).slice(2),
212+
MMMM: this.getMonthName(this.getMonth(date), translationTemp.months),
213+
MMM: this.getMonthNameAbbr(this.getMonth(date), translationTemp.monthsAbbr),
214+
MM: (`0${month}`).slice(-2),
215+
M: month,
216+
o: this.getNthSuffix(this.getDate(date)),
217+
E: this.getDayNameAbbr(date, translationTemp.days),
218+
}
219+
220+
const REGEX_FORMAT = /y{4}|y{2}|M{1,4}(?![aäe])|d{1,2}|o{1}|E{1}(?![eéi])/g
221+
return formatStr.replace(REGEX_FORMAT, (match) => matches[match] || match)
217222
},
218223

219224
/**

test/unit/specs/DateUtils.spec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,22 @@ describe('DateUtils', () => {
4444
expect(DateUtils.formatDate(new Date(2016, 11, 2), 'dd MMM yyyy')).toEqual('02 Dec 2016')
4545
})
4646

47+
// issue: https://github.com/sumcumo/vue-datepicker/issues/29
48+
it('should format date strings without formatting issues like 03 Nrdv 2016 instead of 03 Nov 2016', () => {
49+
expect(DateUtils.formatDate(new Date(2016, 0, 12), 'd MMM yyyy')).toEqual('12 Jan 2016')
50+
expect(DateUtils.formatDate(new Date(2016, 1, 12), 'd MMM yyyy')).toEqual('12 Feb 2016')
51+
expect(DateUtils.formatDate(new Date(2016, 2, 12), 'd MMM yyyy')).toEqual('12 Mar 2016')
52+
expect(DateUtils.formatDate(new Date(2016, 3, 12), 'd MMM yyyy')).toEqual('12 Apr 2016')
53+
expect(DateUtils.formatDate(new Date(2016, 4, 12), 'd MMM yyyy')).toEqual('12 May 2016')
54+
expect(DateUtils.formatDate(new Date(2016, 5, 12), 'd MMM yyyy')).toEqual('12 Jun 2016')
55+
expect(DateUtils.formatDate(new Date(2016, 6, 12), 'd MMM yyyy')).toEqual('12 Jul 2016')
56+
expect(DateUtils.formatDate(new Date(2016, 7, 12), 'd MMM yyyy')).toEqual('12 Aug 2016')
57+
expect(DateUtils.formatDate(new Date(2016, 8, 12), 'd MMM yyyy')).toEqual('12 Sep 2016')
58+
expect(DateUtils.formatDate(new Date(2016, 9, 12), 'd MMM yyyy')).toEqual('12 Oct 2016')
59+
expect(DateUtils.formatDate(new Date(2016, 10, 12), 'd MMM yyyy')).toEqual('12 Nov 2016')
60+
expect(DateUtils.formatDate(new Date(2016, 11, 12), 'd MMM yyyy')).toEqual('12 Dec 2016')
61+
})
62+
4763
it('should parse english dates', () => {
4864
expect(DateUtils.parseDate('16 April 2020', 'd MMMM yyyy', en, null))
4965
.toEqual('2020-04-16T00:00:00Z')

0 commit comments

Comments
 (0)