From 8a0811226679a6128714a0ed188f2d0ef0254313 Mon Sep 17 00:00:00 2001 From: Jukka Raimovaara Date: Mon, 26 Oct 2020 11:40:08 +0200 Subject: [PATCH] fix: customParseFormat plugin supports parsing localizedFormats (#1110) --- src/plugin/customParseFormat/index.js | 3 +++ src/plugin/localizedFormat/index.js | 16 +++------------- src/plugin/localizedFormat/utils.js | 13 +++++++++++++ test/plugin/customParseFormat.test.js | 17 +++++++++++++++++ 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/plugin/customParseFormat/index.js b/src/plugin/customParseFormat/index.js index d96df6fe5..034b5d5f6 100644 --- a/src/plugin/customParseFormat/index.js +++ b/src/plugin/customParseFormat/index.js @@ -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 @@ -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) { diff --git a/src/plugin/localizedFormat/index.js b/src/plugin/localizedFormat/index.js index 425226f72..a9b88b3ac 100644 --- a/src/plugin/localizedFormat/index.js +++ b/src/plugin/localizedFormat/index.js @@ -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) } } diff --git a/src/plugin/localizedFormat/utils.js b/src/plugin/localizedFormat/utils.js index d551194fe..b6284d8e9 100644 --- a/src/plugin/localizedFormat/utils.js +++ b/src/plugin/localizedFormat/utils.js @@ -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]) +}) diff --git a/test/plugin/customParseFormat.test.js b/test/plugin/customParseFormat.test.js index 14dd830d3..e1cf9e562 100644 --- a/test/plugin/customParseFormat.test.js +++ b/test/plugin/customParseFormat.test.js @@ -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()) @@ -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 ]'