diff --git a/README.md b/README.md index 52b35f03c..acac138fb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -English | [简体中文](./ReadMe.zh-CN.md) +English | [简体中文](./README.zh-CN.md)
diff --git a/src/constant.js b/src/constant.js index b64692a78..2bdd63aa5 100644 --- a/src/constant.js +++ b/src/constant.js @@ -19,3 +19,12 @@ export const M = 'month' export const Q = 'quarter' export const Y = 'year' export const DATE = 'date' + +export const WEEKS = 'Sunday.Monday.Tuesday.Wednesday.Thursday.Friday.Saturday'.split('.') +export const MONTHS = 'January.February.March.April.May.June.July.August.September.October.November.December'.split('.') + +export const FORMAT_DEFAULT = 'YYYY-MM-DDTHH:mm:ssZ' + +// regex +export const REGEX_PARSE = /^(\d{4})-?(\d{2})-?(\d{1,2})$/ +export const REGEX_FORMAT = /Y{2,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}/g diff --git a/src/index.js b/src/index.js index 7affa875d..9aff59660 100644 --- a/src/index.js +++ b/src/index.js @@ -7,7 +7,7 @@ const parseConfig = (config) => { if (!config) return new Date() if (config instanceof Date) return config // eslint-disable-next-line no-cond-assign - if (reg = String(config).match(/^(\d{4})-?(\d{2})-?(\d{1,2})$/)) { + if (reg = String(config).match(C.REGEX_PARSE)) { // 2018-08-08 or 20180808 return new Date(reg[1], reg[2] - 1, reg[3]) } @@ -90,7 +90,8 @@ class Dayjs { return this.$d.getTime() } - startOf(units, isStartOf = true) { // isStartOf -> endOf + startOf(units, startOf) { // startOf -> endOf + const isStartOf = startOf !== undefined ? startOf : true const unit = Utils.prettyUnit(units) const instanceFactory = (d, m, y = this.$y) => { const ins = new Dayjs(new Date(y, m, d)) @@ -207,11 +208,9 @@ class Dayjs { return this.add(number * -1, string) } - format(formatStr = 'YYYY-MM-DDTHH:mm:ssZ') { - const weeks = 'Sunday.Monday.Tuesday.Wednesday.Thursday.Friday.Saturday'.split('.') - const months = 'January.February.March.April.May.June.July.August.September.October.November.December'.split('.') - - return formatStr.replace(/Y{2,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|m{1,2}|s{1,2}|Z{1,2}/g, (match) => { + format(formatStr) { + const str = formatStr || C.FORMAT_DEFAULT + return str.replace(C.REGEX_FORMAT, (match) => { switch (match) { case 'YY': return String(this.$y).slice(-2) @@ -220,31 +219,39 @@ class Dayjs { case 'M': return String(this.$M + 1) case 'MM': - return Utils.padStart(String(this.$M + 1), 2, '0') + return Utils.padStart(this.$M + 1, 2, '0') case 'MMM': - return months[this.$M].slice(0, 3) + return C.MONTHS[this.$M].slice(0, 3) case 'MMMM': - return months[this.$M] + return C.MONTHS[this.$M] case 'D': return String(this.$D) case 'DD': - return Utils.padStart(String(this.$D), 2, '0') + return Utils.padStart(this.$D, 2, '0') case 'd': return String(this.$W) case 'dddd': - return weeks[this.$W] + return C.WEEKS[this.$W] case 'H': return String(this.$H) case 'HH': - return Utils.padStart(String(this.$H), 2, '0') + return Utils.padStart(this.$H, 2, '0') + case 'h': + case 'hh': + if (this.$H === 0) return 12 + return Utils.padStart(this.$H < 13 ? this.$H : this.$H - 12, match === 'hh' ? 2 : 1, '0') + case 'a': + return this.$H < 12 ? 'am' : 'pm' + case 'A': + return this.$H < 12 ? 'AM' : 'PM' case 'm': return String(this.$m) case 'mm': - return Utils.padStart(String(this.$m), 2, '0') + return Utils.padStart(this.$m, 2, '0') case 's': return String(this.$s) case 'ss': - return Utils.padStart(String(this.$s), 2, '0') + return Utils.padStart(this.$s, 2, '0') case 'Z': return `${this.$zoneStr.slice(0, -2)}:00` default: // 'ZZ' @@ -253,7 +260,7 @@ class Dayjs { }) } - diff(input, units, float = false) { + diff(input, units, float) { const unit = Utils.prettyUnit(units) const that = input instanceof Dayjs ? input : new Dayjs(input) const diff = this - that diff --git a/src/utils.js b/src/utils.js index 37901154a..607a0ef0a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,12 +1,13 @@ export const padStart = (string, length, pad) => { - if (!string || string.length >= length) return string - return `${Array((length + 1) - string.length).join(pad)}${string}` + const s = String(string) + if (!string || s.length >= length) return string + return `${Array((length + 1) - s.length).join(pad)}${string}` } export const isNumber = n => (!Number.isNaN(parseFloat(n)) && Number.isFinite(n)) export const monthDiff = (a, b) => { - // function from moment.js monthDiff + // function from moment.js in order to keep the same result const wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()) const anchor = a.clone().add(wholeMonthDiff, 'months') let anchor2 @@ -18,7 +19,7 @@ export const monthDiff = (a, b) => { anchor2 = a.clone().add(wholeMonthDiff + 1, 'months') adjust = (b - anchor) / (anchor2 - anchor) } - return Number(-(wholeMonthDiff + adjust)) || 0 + return Number(-(wholeMonthDiff + adjust)) } export const absFloor = n => (n < 0 ? Math.ceil(n) || 0 : Math.floor(n)) diff --git a/test/display.test.js b/test/display.test.js index 723f0856f..12b875a7c 100644 --- a/test/display.test.js +++ b/test/display.test.js @@ -41,6 +41,30 @@ it('Format Hour H HH 24-hour', () => { expect(dayjs().format('HH')).toBe(moment().format('HH')) }) +it('Format Hour h hh 12-hour', () => { + MockDate.set(new Date('2018-05-02T00:00:00.000')) + expect(dayjs().format('h')).toBe(moment().format('h')) + expect(dayjs().format('hh')).toBe(moment().format('hh')) + + MockDate.set(new Date('2018-05-02T01:00:00.000')) + expect(dayjs().format('h')).toBe(moment().format('h')) + expect(dayjs().format('hh')).toBe(moment().format('hh')) + + MockDate.set(new Date('2018-05-02T23:00:00.000')) + expect(dayjs().format('h')).toBe(moment().format('h')) + expect(dayjs().format('hh')).toBe(moment().format('hh')) +}) + +it('Format meridiens a A am / pm', () => { + MockDate.set(new Date('2018-05-02T01:00:00.000')) + expect(dayjs().format('a')).toBe(moment().format('a')) + expect(dayjs().format('A')).toBe(moment().format('A')) + + MockDate.set(new Date('2018-05-02T23:00:00.000')) + expect(dayjs().format('a')).toBe(moment().format('a')) + expect(dayjs().format('A')).toBe(moment().format('A')) +}) + it('Format Minute m mm', () => { expect(dayjs().format('m')).toBe(moment().format('m')) expect(dayjs().format('mm')).toBe(moment().format('mm'))