diff --git a/src/index.js b/src/index.js index f71f97f7..ebfad144 100644 --- a/src/index.js +++ b/src/index.js @@ -28,13 +28,14 @@ const parseLocale = (preset, object, isLocal) => { return l || (!isLocal && L) } -const dayjs = (date, c, pl) => { +const dayjs = function (date, c) { if (isDayjs(date)) { return date.clone() } // eslint-disable-next-line no-nested-ternary - const cfg = c ? (typeof c === 'string' ? { format: c, pl } : c) : {} + const cfg = typeof c === 'object' ? c : {} cfg.date = date + cfg.args = arguments// eslint-disable-line prefer-rest-params return new Dayjs(cfg) // eslint-disable-line no-use-before-define } diff --git a/src/plugin/customParseFormat/index.js b/src/plugin/customParseFormat/index.js index 6d754f10..850c0483 100644 --- a/src/plugin/customParseFormat/index.js +++ b/src/plugin/customParseFormat/index.js @@ -181,16 +181,26 @@ export default (o, C, d) => { proto.parse = function (cfg) { const { date, - format, - pl, - utc + utc, + args } = cfg this.$u = utc - if (format) { - locale = pl ? d.Ls[pl] : this.$locale() + const format = args[1] + if (typeof format === 'string') { + const isStrictWithoutLocale = args[2] === true + const isStrictWithLocale = args[3] === true + const isStrict = isStrictWithoutLocale || isStrictWithLocale + let pl = args[2] + if (isStrictWithLocale) [,, pl] = args + if (!isStrictWithoutLocale) { + locale = pl ? d.Ls[pl] : this.$locale() + } this.$d = parseFormattedInput(date, format, utc) this.init(cfg) - if (pl) this.$L = pl + if (isStrict && date !== this.format(format)) { + this.$d = new Date('') + } + if (pl && pl !== true) this.$L = pl } else { oldParse.call(this, cfg) } diff --git a/src/plugin/duration/index.js b/src/plugin/duration/index.js index 9d3361f4..28031b12 100644 --- a/src/plugin/duration/index.js +++ b/src/plugin/duration/index.js @@ -95,7 +95,7 @@ class Duration { seconds += this.$d.milliseconds / 1000 } const S = seconds ? `${seconds}S` : '' - const T = (H || M || S) ? 'T' : '' + const T = (H || m || S) ? 'T' : '' const result = `P${Y}${M}${D}${T}${H}${m}${S}` return result === 'P' ? 'P0D' : result } diff --git a/src/plugin/relativeTime/index.js b/src/plugin/relativeTime/index.js index 10a8f5de..022fbfbd 100644 --- a/src/plugin/relativeTime/index.js +++ b/src/plugin/relativeTime/index.js @@ -3,7 +3,7 @@ import * as C from '../../constant' export default (o, c, d) => { o = o || {} const proto = c.prototype - d.en.relativeTime = { + const relObj = { future: 'in %s', past: '%s ago', s: 'a few seconds', @@ -18,8 +18,9 @@ export default (o, c, d) => { y: 'a year', yy: '%d years' } + d.en.relativeTime = relObj const fromTo = (input, withoutSuffix, instance, isFrom) => { - const loc = instance.$locale().relativeTime + const loc = instance.$locale().relativeTime || relObj const T = o.thresholds || [ { l: 's', r: 44, d: C.S }, { l: 'm', r: 89 }, diff --git a/src/plugin/utc/index.js b/src/plugin/utc/index.js index 606a831a..a5bc6353 100644 --- a/src/plugin/utc/index.js +++ b/src/plugin/utc/index.js @@ -3,8 +3,8 @@ import { MILLISECONDS_A_MINUTE, MIN } from '../../constant' export default (option, Dayjs, dayjs) => { const localOffset = (new Date()).getTimezoneOffset() const proto = Dayjs.prototype - dayjs.utc = function (date, format) { - const cfg = { date, utc: true, format } + dayjs.utc = function (date) { + const cfg = { date, utc: true, args: arguments } // eslint-disable-line prefer-rest-params return new Dayjs(cfg) // eslint-disable-line no-use-before-define } diff --git a/src/plugin/weekOfYear/index.js b/src/plugin/weekOfYear/index.js index f0c6088d..13ec97c4 100644 --- a/src/plugin/weekOfYear/index.js +++ b/src/plugin/weekOfYear/index.js @@ -1,6 +1,6 @@ import { MS, Y, D, W } from '../../constant' -export default (o, c) => { +export default (o, c, d) => { const proto = c.prototype proto.week = function (week = null) { if (week !== null) { @@ -8,17 +8,18 @@ export default (o, c) => { } const yearStart = this.$locale().yearStart || 1 if (this.month() === 11 && this.date() > 25) { - const nextYearStartDay = this.startOf(Y).add(1, Y).date(yearStart) - const thisEndOfWeek = this.endOf(W) + // d(this) is for badMutable + const nextYearStartDay = d(this).startOf(Y).add(1, Y).date(yearStart) + const thisEndOfWeek = d(this).endOf(W) if (nextYearStartDay.isBefore(thisEndOfWeek)) { return 1 } } - const yearStartDay = this.startOf(Y).date(yearStart) + const yearStartDay = d(this).startOf(Y).date(yearStart) const yearStartWeek = yearStartDay.startOf(W).subtract(1, MS) const diffInWeek = this.diff(yearStartWeek, W, true) if (diffInWeek < 0) { - return this.startOf('week').week() + return d(this).startOf('week').week() } return Math.ceil(diffInWeek) } diff --git a/test/plugin/badMutable.test.js b/test/plugin/badMutable.test.js index 5b38bc89..fb4dc723 100644 --- a/test/plugin/badMutable.test.js +++ b/test/plugin/badMutable.test.js @@ -2,9 +2,11 @@ import MockDate from 'mockdate' import moment from 'moment' import dayjs from '../../src' import badMutable from '../../src/plugin/badMutable' +import weekOfYear from '../../src/plugin/weekOfYear' import '../../src/locale/zh-cn' dayjs.extend(badMutable) +dayjs.extend(weekOfYear) beforeEach(() => { MockDate.set(new Date()) @@ -175,3 +177,10 @@ it('isAfter isBefore isSame', () => { expect(d.format()).toBe(format) expect(d.isAfter()).toBe(false) }) + +it('WeekOfYear get week won"t change instance', () => { + const d = dayjs() + const format = d.format() + d.week() + expect(d.format()).toBe(format) +}) diff --git a/test/plugin/customParseFormat.test.js b/test/plugin/customParseFormat.test.js index c7337705..0e026031 100644 --- a/test/plugin/customParseFormat.test.js +++ b/test/plugin/customParseFormat.test.js @@ -146,13 +146,13 @@ it('parse month from string with locale in config', () => { const input = '2018 лютий 03' const format = 'YYYY MMMM DD' - expect(dayjs(input, { format, locale: uk }).valueOf()).toBe(moment(input, format, 'uk').valueOf()) + expect(dayjs(input, format, 'uk').valueOf()).toBe(moment(input, format, 'uk').valueOf()) }) it('parse month from short string with locale in config', () => { const input = '2018 трав 03' const format = 'YYYY MMM DD' - expect(dayjs(input, { format, locale: uk }).valueOf()).toBe(moment(input, format, 'uk').valueOf()) + expect(dayjs(input, format, 'uk').valueOf()).toBe(moment(input, format, 'uk').valueOf()) }) it('parse month from short string with locale in argument', () => { @@ -232,3 +232,19 @@ it('correctly parse ordinal', () => { expect(dayjsCN.locale()) .toBe(momentCN.locale()) }) + + +describe('Strict mode', () => { + it('without locale', () => { + const input = '1970-00-00' + const format = 'YYYY-MM-DD' + expect(dayjs(input, format).isValid()).toBe(true) + expect(dayjs(input, format, true).isValid()).toBe(false) + }) + it('with locale', () => { + const input = '2018 三月 99' + const format = 'YYYY MMMM DD' + expect(dayjs(input, format, 'zh-cn').isValid()).toBe(true) + expect(dayjs(input, format, 'zh-cn', true).isValid()).toBe(false) + }) +}) diff --git a/test/plugin/duration.test.js b/test/plugin/duration.test.js index 350053a9..e854d914 100644 --- a/test/plugin/duration.test.js +++ b/test/plugin/duration.test.js @@ -23,7 +23,7 @@ describe('Creating', () => { }) it('two argument will bubble up to the next', () => { expect(dayjs.duration(59, 'seconds').toISOString()).toBe('PT59S') - expect(dayjs.duration(60, 'seconds').toISOString()).toBe('P1M') + expect(dayjs.duration(60, 'seconds').toISOString()).toBe('PT1M') expect(dayjs.duration(13213, 'seconds').toISOString()).toBe('PT3H40M13S') }) it('object with float', () => { @@ -78,7 +78,7 @@ it('Is duration', () => { it('toJSON', () => { expect(JSON.stringify({ postDuration: dayjs.duration(5, 'minutes') - })).toBe('{"postDuration":"P5M"}') + })).toBe('{"postDuration":"PT5M"}') }) describe('Humanize', () => { diff --git a/test/plugin/isoWeek.test.js b/test/plugin/isoWeek.test.js index 8c2157f2..b86a6d6a 100644 --- a/test/plugin/isoWeek.test.js +++ b/test/plugin/isoWeek.test.js @@ -38,6 +38,7 @@ it('isoWeekday', () => { for (let i = 0; i < 7; i += 1) { expect(dayjs().add(i, 'day').isoWeekday()).toBe(moment().add(i, 'day').isoWeekday()) expect(dayjs().isoWeekday(i).valueOf()).toBe(moment().isoWeekday(i).valueOf()) + expect(dayjs().add(1, 'day').isoWeekday(i).valueOf()).toBe(moment().add(1, 'day').isoWeekday(i).valueOf()) } }) diff --git a/test/plugin/relativeTime.test.js b/test/plugin/relativeTime.test.js index e8a26e0a..19994381 100644 --- a/test/plugin/relativeTime.test.js +++ b/test/plugin/relativeTime.test.js @@ -137,3 +137,9 @@ it('Custom thresholds and rounding support', () => { }) expect(dayjs().subtract(45, 'm').fromNow()).toBe('45 minutes ago') }) + +it('Locale without relativeTime config fallback', () => { + expect(dayjs().locale({ + name: 'test-locale' + }).fromNow()).toEqual(expect.any(String)) +})