Skip to content

Commit

Permalink
fix: customParseFormat plugin supports parsing localizedFormats (#1110)
Browse files Browse the repository at this point in the history
  • Loading branch information
xvaara authored and iamkun committed Oct 30, 2020
1 parent a3106a8 commit 402b603
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 13 deletions.
3 changes: 3 additions & 0 deletions src/plugin/customParseFormat/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
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 match1 = /\d/ // 0 - 9
Expand Down Expand Up @@ -118,6 +120,7 @@ function correctHours(time) {
}

function makeParser(format) {
format = u(format, locale.formats)
const array = format.match(formattingTokens)
const { length } = array
for (let i = 0; i < length; i += 1) {
Expand Down
16 changes: 3 additions & 13 deletions src/plugin/localizedFormat/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import { FORMAT_DEFAULT } from '../../constant'
import { t } from './utils'
import { u, englishFormats } from './utils'

export default (o, c, d) => {
const proto = c.prototype
const oldFormat = proto.format
const englishFormats = {
LTS: 'h:mm:ss A',
LT: 'h:mm A',
L: 'MM/DD/YYYY',
LL: 'MMMM D, YYYY',
LLL: 'MMMM D, YYYY h:mm A',
LLLL: 'dddd, MMMM D, YYYY h:mm A'
}

d.en.formats = englishFormats
proto.format = function (formatStr = FORMAT_DEFAULT) {
const { formats = {} } = this.$locale()
const result = formatStr.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g, (_, a, b) => {
const B = b && b.toUpperCase()
return a || formats[b] || englishFormats[b] || t(formats[B])
})
const result = u(formatStr, formats)
return oldFormat.call(this, result)
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/plugin/localizedFormat/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,16 @@
export const t = format =>
format.replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g, (_, a, b) => a || b.slice(1))

export const englishFormats = {
LTS: 'h:mm:ss A',
LT: 'h:mm A',
L: 'MM/DD/YYYY',
LL: 'MMMM D, YYYY',
LLL: 'MMMM D, YYYY h:mm A',
LLLL: 'dddd, MMMM D, YYYY h:mm A'
}

export const u = (formatStr, formats) => formatStr.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g, (_, a, b) => {
const B = b && b.toUpperCase()
return a || formats[b] || englishFormats[b] || t(formats[B])
})
17 changes: 17 additions & 0 deletions test/plugin/customParseFormat.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import MockDate from 'mockdate'
import moment from 'moment'
import dayjs from '../../src'
import customParseFormat from '../../src/plugin/customParseFormat'
import localizedFormats from '../../src/plugin/localizedFormat'
import uk from '../../src/locale/uk'
import '../../src/locale/zh-cn'
import '../../src/locale/ru'

dayjs.extend(customParseFormat)
dayjs.extend(localizedFormats)

beforeEach(() => {
MockDate.set(new Date())
Expand Down Expand Up @@ -72,6 +74,21 @@ it('recognizes noon in small letters', () => {
expect(dayjs(input, format).valueOf()).toBe(moment(input, format).valueOf())
})

describe('parse localizedFormats', () => {
['zh-cn', 'ru', 'uk', 'en'].forEach((lo) => {
it(`Locale: ${lo}`, () => {
const input = '2018-05-02 01:02:03.004'
dayjs.locale(lo)
moment.locale(lo)
const longDateFormats = ['LT', 'LTS', 'L', 'LL', 'l', 'll', 'lll', 'l LT', 'LL [l] LTS'] // TODO: fix LLL, LLLL and llll
longDateFormats.forEach((f) => {
const localizedInput = moment(input).format(f)
expect(dayjs(localizedInput, f).valueOf()).toBe(moment(localizedInput, f).valueOf())
})
})
})
})

it('leaves non-token parts of the format intact', () => {
const input = '2018-05-02 12:00 +0000 S:/-.() SS h '
const format = 'YYYY-MM-DD HH:mm ZZ [S]:/-.()[ SS h ]'
Expand Down

0 comments on commit 402b603

Please sign in to comment.