Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Update locale month to support both array and function #581

Merged
merged 4 commits into from
Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,14 +278,15 @@ class Dayjs {
const str = formatStr || C.FORMAT_DEFAULT
const zoneStr = Utils.z(this)
const locale = this.$locale()
const { $H, $m, $M } = this
const {
weekdays, months, meridiem
} = locale
const getShort = (arr, index, full, length) => (
(arr && arr[index]) || full[index].substr(0, length)
(arr && (arr[index] || arr(this, str))) || full[index].substr(0, length)
)
const get$H = num => (
Utils.s(this.$H % 12 || 12, num, '0')
Utils.s($H % 12 || 12, num, '0')
)

const meridiemFunc = meridiem || ((hour, minute, isLowercase) => {
Expand All @@ -295,32 +296,32 @@ class Dayjs {

const matches = {
YY: String(this.$y).slice(-2),
YYYY: String(this.$y),
M: String(this.$M + 1),
MM: Utils.s(this.$M + 1, 2, '0'),
MMM: getShort(locale.monthsShort, this.$M, months, 3),
MMMM: months[this.$M],
D: String(this.$D),
YYYY: this.$y,
M: $M + 1,
MM: Utils.s($M + 1, 2, '0'),
MMM: getShort(locale.monthsShort, $M, months, 3),
MMMM: months[$M] || months(this, str),
D: this.$D,
DD: Utils.s(this.$D, 2, '0'),
d: String(this.$W),
d: this.$W,
dd: getShort(locale.weekdaysMin, this.$W, weekdays, 2),
ddd: getShort(locale.weekdaysShort, this.$W, weekdays, 3),
dddd: weekdays[this.$W],
H: String(this.$H),
HH: Utils.s(this.$H, 2, '0'),
H: $H,
HH: Utils.s($H, 2, '0'),
h: get$H(1),
hh: get$H(2),
a: meridiemFunc(this.$H, this.$m, true),
A: meridiemFunc(this.$H, this.$m, false),
m: String(this.$m),
mm: Utils.s(this.$m, 2, '0'),
s: String(this.$s),
a: meridiemFunc($H, $m, true),
A: meridiemFunc($H, $m, false),
m: $m,
mm: Utils.s($m, 2, '0'),
s: this.$s,
ss: Utils.s(this.$s, 2, '0'),
SSS: Utils.s(this.$ms, 3, '0'),
Z: zoneStr // 'ZZ' logic below
}

return str.replace(C.REGEX_FORMAT, (match, $1) => $1 || matches[match] || zoneStr.replace(':', '')) // 'ZZ'
return String(str.replace(C.REGEX_FORMAT, (match, $1) => $1 || matches[match] || zoneStr.replace(':', ''))) // 'ZZ'
}

utcOffset() {
Expand Down
21 changes: 19 additions & 2 deletions src/locale/ru.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
import dayjs from 'dayjs'

const monthFormat = 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')
const monthStandalone = 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_')

const monthShortFormat = 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_')
const monthShortStandalone = 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_')

const MONTHS_IN_FORMAT = /D[oD]?(\[[^[\]]*\]|\s)+MMMM?/
const locale = {
name: 'ru',
weekdays: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),
weekdaysShort: 'вск_пнд_втр_срд_чтв_птн_сбт'.split('_'),
weekdaysMin: 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
months: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),
monthsShort: 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),
months: (dayjsInstance, format) => {
if (MONTHS_IN_FORMAT.test(format)) {
return monthFormat[dayjsInstance.month()]
}
return monthStandalone[dayjsInstance.month()]
},
monthsShort: (dayjsInstance, format) => {
if (MONTHS_IN_FORMAT.test(format)) {
return monthShortFormat[dayjsInstance.month()]
}
return monthShortStandalone[dayjsInstance.month()]
},
weekStart: 1,
formats: {
LT: 'H:mm',
Expand Down
16 changes: 14 additions & 2 deletions test/locale/keys.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,23 @@ Locale.forEach((locale) => {
expect(weekdays).toEqual(expect.any(Array))

if (weekdaysShort) expect(weekdaysShort).toEqual(expect.any(Array))
if (monthsShort) expect(monthsShort).toEqual(expect.any(Array))
if (weekdaysMin) expect(weekdaysMin).toEqual(expect.any(Array))
if (weekStart) expect(weekStart).toEqual(expect.any(Number))

expect(months).toEqual(expect.any(Array))
// months could be a function or array
if (Array.isArray(months)) {
expect(months).toEqual(expect.any(Array))
} else {
expect(months(dayjs(), 'str')).toEqual(expect.any(String))
}
// monthsShort could be a function or array
if (monthsShort) {
if (Array.isArray(monthsShort)) {
expect(monthsShort).toEqual(expect.any(Array))
} else {
expect(monthsShort(dayjs(), 'str')).toEqual(expect.any(String))
}
}
// function pass date return string or number or null
if (name !== 'en') { // en ordinal set in advancedFormat
for (let i = 1; i <= 31; i += 1) {
Expand Down
25 changes: 25 additions & 0 deletions test/locale/ru.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import moment from 'moment'
import MockDate from 'mockdate'
import dayjs from '../../src'
import '../../src/locale/ru'

beforeEach(() => {
MockDate.set(new Date())
})

afterEach(() => {
MockDate.reset()
})

it('Format Month with locale function', () => {
for (let i = 0; i <= 7; i += 1) {
const dayjsRU = dayjs().locale('ru').add(i, 'day')
const momentRU = moment().locale('ru').add(i, 'day')
const testFormat1 = 'DD MMMM YYYY MMM'
const testFormat2 = 'MMMM'
const testFormat3 = 'MMM'
expect(dayjsRU.format(testFormat1)).toEqual(momentRU.format(testFormat1))
expect(dayjsRU.format(testFormat2)).toEqual(momentRU.format(testFormat2))
expect(dayjsRU.format(testFormat3)).toEqual(momentRU.format(testFormat3))
}
})