Skip to content

Commit bf347c3

Browse files
authoredMay 14, 2020
fix: Fix locale month function bug (#908)
1 parent 97856c6 commit bf347c3

File tree

7 files changed

+68
-26
lines changed

7 files changed

+68
-26
lines changed
 

‎src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ class Dayjs {
305305
M: $M + 1,
306306
MM: Utils.s($M + 1, 2, '0'),
307307
MMM: getShort(locale.monthsShort, $M, months, 3),
308-
MMMM: months[$M] || months(this, str),
308+
MMMM: getShort(months, $M),
309309
D: this.$D,
310310
DD: Utils.s(this.$D, 2, '0'),
311311
d: String(this.$W),

‎src/locale/ru.js

+19-12
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,31 @@ function relativeTimeWithPlural(number, withoutSuffix, key) {
2727

2828
return `${number} ${plural(format[key], +number)}`
2929
}
30+
const months = (dayjsInstance, format) => {
31+
if (MONTHS_IN_FORMAT.test(format)) {
32+
return monthFormat[dayjsInstance.month()]
33+
}
34+
return monthStandalone[dayjsInstance.month()]
35+
}
36+
months.s = monthStandalone
37+
months.f = monthFormat
38+
39+
const monthsShort = (dayjsInstance, format) => {
40+
if (MONTHS_IN_FORMAT.test(format)) {
41+
return monthShortFormat[dayjsInstance.month()]
42+
}
43+
return monthShortStandalone[dayjsInstance.month()]
44+
}
45+
monthsShort.s = monthShortStandalone
46+
monthsShort.f = monthShortFormat
3047

3148
const locale = {
3249
name: 'ru',
3350
weekdays: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
3451
weekdaysShort: 'вск_пнд_втр_срд_чтв_птн_сбт'.split('_'),
3552
weekdaysMin: 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
36-
months: (dayjsInstance, format) => {
37-
if (MONTHS_IN_FORMAT.test(format)) {
38-
return monthFormat[dayjsInstance.month()]
39-
}
40-
return monthStandalone[dayjsInstance.month()]
41-
},
42-
monthsShort: (dayjsInstance, format) => {
43-
if (MONTHS_IN_FORMAT.test(format)) {
44-
return monthShortFormat[dayjsInstance.month()]
45-
}
46-
return monthShortStandalone[dayjsInstance.month()]
47-
},
53+
months,
54+
monthsShort,
4855
weekStart: 1,
4956
formats: {
5057
LT: 'H:mm',

‎src/plugin/customParseFormat/index.js

+14-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const matchUpperCaseAMPM = /[AP]M/
99
const matchLowerCaseAMPM = /[ap]m/
1010
const matchSigned = /[+-]?\d+/ // -inf - inf
1111
const matchOffset = /[+-]\d\d:?\d\d/ // +00:00 -00:00 +0000 or -0000
12-
const matchWord = /\d*[^\s\d-:/.()]+/ // Word
12+
const matchWord = /\d*[^\s\d-:/()]+/ // Word
1313

1414
let locale
1515

@@ -30,6 +30,13 @@ const zoneExpressions = [matchOffset, function (input) {
3030
zone.offset = offsetFromString(input)
3131
}]
3232

33+
const getLocalePart = (name) => {
34+
const part = locale[name]
35+
return part && (
36+
part.indexOf ? part : part.s.concat(part.f)
37+
)
38+
}
39+
3340
const expressions = {
3441
A: [matchUpperCaseAMPM, function (input) {
3542
this.afternoon = input === 'PM'
@@ -69,22 +76,21 @@ const expressions = {
6976
M: [match1to2, addInput('month')],
7077
MM: [match2, addInput('month')],
7178
MMM: [matchWord, function (input) {
72-
const { months, monthsShort } = locale
73-
const matchIndex = monthsShort
74-
? monthsShort.findIndex(month => month === input)
75-
: months.findIndex(month => month.substr(0, 3) === input)
79+
const months = getLocalePart('months')
80+
const monthsShort = getLocalePart('monthsShort')
81+
const matchIndex = (monthsShort || months.map(_ => _.substr(0, 3))).indexOf(input)
7682
if (matchIndex < 0) {
7783
throw new Error()
7884
}
79-
this.month = matchIndex + 1
85+
this.month = (matchIndex + 1) % 12
8086
}],
8187
MMMM: [matchWord, function (input) {
82-
const { months } = locale
88+
const months = getLocalePart('months')
8389
const matchIndex = months.indexOf(input)
8490
if (matchIndex < 0) {
8591
throw new Error()
8692
}
87-
this.month = matchIndex + 1
93+
this.month = (matchIndex + 1) % 12
8894
}],
8995
Y: [matchSigned, addInput('year')],
9096
YY: [match2, function (input) {

‎src/plugin/localeData/index.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
export default (o, c, dayjs) => { // locale needed later
22
const proto = c.prototype
3+
const getLocalePart = part => (part && (part.indexOf ? part : part.s))
34
const getShort = (ins, target, full, num) => {
45
const locale = ins.name ? ins : ins.$locale()
5-
if (!locale[target]) {
6-
return locale[full].map(f => f.substr(0, num))
7-
}
8-
return locale[target]
6+
const targetLocale = getLocalePart(locale[target])
7+
const fullLocale = getLocalePart(locale[full])
8+
return targetLocale || fullLocale.map(f => f.substr(0, num))
99
}
1010
const getDayjsLocaleObject = () => dayjs.Ls[dayjs.locale()]
1111
const localeData = function () {
@@ -38,7 +38,7 @@ export default (o, c, dayjs) => { // locale needed later
3838
}
3939
}
4040

41-
dayjs.months = () => getDayjsLocaleObject().months
41+
dayjs.months = () => getShort(getDayjsLocaleObject(), 'months')
4242

4343
dayjs.monthsShort = () => getShort(getDayjsLocaleObject(), 'monthsShort', 'months', 3)
4444

‎test/locale/keys.test.js

+4
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@ Locale.forEach((locale) => {
4545
expect(months).toEqual(expect.any(Array))
4646
} else {
4747
expect(months(dayjs(), 'str')).toEqual(expect.any(String))
48+
expect(months.f).toEqual(expect.any(Array))
49+
expect(months.s).toEqual(expect.any(Array))
4850
}
4951
// monthsShort could be a function or array
5052
if (monthsShort) {
5153
if (Array.isArray(monthsShort)) {
5254
expect(monthsShort).toEqual(expect.any(Array))
5355
} else {
5456
expect(monthsShort(dayjs(), 'str')).toEqual(expect.any(String))
57+
expect(monthsShort.f).toEqual(expect.any(Array))
58+
expect(monthsShort.s).toEqual(expect.any(Array))
5559
}
5660
}
5761
// function pass date return string or number or null

‎test/plugin/customParseFormat.test.js

+13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import dayjs from '../../src'
44
import customParseFormat from '../../src/plugin/customParseFormat'
55
import uk from '../../src/locale/uk'
66
import '../../src/locale/zh-cn'
7+
import '../../src/locale/ru'
78

89
dayjs.extend(customParseFormat)
910

@@ -233,6 +234,18 @@ it('correctly parse ordinal', () => {
233234
.toBe(momentCN.locale())
234235
})
235236

237+
describe('month function locale', () => {
238+
it('MMMM', () => {
239+
const input = '08 мая 2020'
240+
const format = 'DD MMMM YYYY'
241+
expect(dayjs(input, format, 'ru').valueOf()).toBe(moment(input, format, 'ru').valueOf())
242+
})
243+
it('MMM', () => {
244+
const input = '08 февр. 2020'
245+
const format = 'DD MMM YYYY'
246+
expect(dayjs(input, format, 'ru').valueOf()).toBe(moment(input, format, 'ru').valueOf())
247+
})
248+
})
236249

237250
describe('Strict mode', () => {
238251
it('without locale', () => {

‎test/plugin/localeData.test.js

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import localeData from '../../src/plugin/localeData'
55
import localizedFormat from '../../src/plugin/localizedFormat'
66
import '../../src/locale/fr'
77
import '../../src/locale/zh-cn'
8+
import '../../src/locale/ru'
89

910
dayjs.extend(localizedFormat)
1011
dayjs.extend(localeData)
@@ -65,3 +66,14 @@ it('Listing the months and weekdays', () => {
6566
expect(dayjs.weekdaysMin()).toEqual(moment.weekdaysMin())
6667
})
6768
})
69+
70+
it('Month function', () => {
71+
const dayjsLocaleData = dayjs().locale('ru').localeData()
72+
const momentLocaleData = moment().locale('ru').localeData()
73+
expect(dayjsLocaleData.months()).toEqual(momentLocaleData.months())
74+
expect(dayjsLocaleData.monthsShort()).toEqual(momentLocaleData.monthsShort())
75+
dayjs.locale('ru')
76+
moment.locale('ru')
77+
expect(dayjs.months()).toEqual(moment.months())
78+
expect(dayjs.monthsShort()).toEqual(moment.monthsShort())
79+
})

0 commit comments

Comments
 (0)
Please sign in to comment.