diff --git a/src/plugin/calendar/index.js b/src/plugin/calendar/index.js new file mode 100644 index 00000000..87db1894 --- /dev/null +++ b/src/plugin/calendar/index.js @@ -0,0 +1,29 @@ +export default (o, c, d) => { + const LT = 'h:mm A' + const L = 'MM/DD/YYYY' + const calendarFormat = { + lastDay: `[Yesterday at] ${LT}`, + sameDay: `[Today at] ${LT}`, + nextDay: `[Tomorrow at] ${LT}`, + nextWeek: `dddd [at] ${LT}`, + lastWeek: `[Last] dddd [at] ${LT}`, + sameElse: L + } + const proto = c.prototype + proto.calendar = function (referenceTime, formats) { + const format = formats || calendarFormat + const referenceStartOfDay = d(referenceTime || undefined).startOf('d') + const diff = this.diff(referenceStartOfDay, 'd', true) + const sameElse = 'sameElse' + /* eslint-disable no-nested-ternary */ + const retVal = diff < -6 ? sameElse : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : sameElse + /* eslint-enable no-nested-ternary */ + return this.format(format[retVal] || calendarFormat[retVal]) + } +} + diff --git a/test/plugin/calendar.test.js b/test/plugin/calendar.test.js new file mode 100644 index 00000000..24dec0f7 --- /dev/null +++ b/test/plugin/calendar.test.js @@ -0,0 +1,81 @@ +import MockDate from 'mockdate' +import moment from 'moment' +import dayjs from '../../src' +import calendar from '../../src/plugin/calendar' + +dayjs.extend(calendar) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('No argument && null && undefined', () => { + expect(dayjs().calendar()).toEqual(moment().calendar()) + expect(dayjs().calendar(null)).toEqual(moment().calendar(null)) + expect(dayjs().calendar(undefined)).toEqual(moment().calendar(undefined)) +}) + +it('ReferenceTime', () => { + const now = '2015-01-15T14:21:22.000Z' + const dates = [ + { + name: 'nextDay', + date: '2015-01-14T11:23:55.000Z', + result: 'Tomorrow' + }, + { + name: 'sameDay', + date: '2015-01-15T11:23:55.000Z', + result: 'Today' + }, + { + name: 'nextWeek', + date: '2015-01-09T11:23:55.000Z', + result: 'Thursday' + }, + { + name: 'lastDay', + date: '2015-01-16T11:23:55.000Z', + result: 'Yesterday' + }, + { + name: 'lastWeek', + date: '2015-01-21T11:23:55.000Z', + result: 'Last' + }, + { + name: 'sameElse', + date: '2015-01-01T11:23:55.000Z', + result: '01/15/2015' + }, + { + name: 'sameElse', + date: '2015-02-21T11:23:55.000Z', + result: '01/15/2015' + } + ] + dates.forEach((d) => { + const dayjsResult = dayjs(now).calendar(d.date) + const momentjsResult = moment(now).calendar(d.date) + expect(dayjsResult) + .toEqual(momentjsResult) + expect(dayjsResult.indexOf(d.result) > -1) + .toBe(true) + }) +}) + +it('Custom format', () => { + const format = { + sameDay: '[sameDay]', + sameElse: '[sameElse]' + } + expect(dayjs().calendar(null, format)).toEqual(moment().calendar(null, format)) + const now = '2015-01-15T14:21:22.000Z' + const nextDayWithoutFormat = '2015-01-14T11:23:55.000Z' + expect(dayjs(now).calendar(nextDayWithoutFormat, format)) + .toEqual(moment(now).calendar(nextDayWithoutFormat, format)) +}) diff --git a/types/plugin/calendar.d.ts b/types/plugin/calendar.d.ts new file mode 100644 index 00000000..a8d064fd --- /dev/null +++ b/types/plugin/calendar.d.ts @@ -0,0 +1,10 @@ +import { PluginFunc, ConfigType } from 'dayjs' + +declare const plugin: PluginFunc +export = plugin + +declare module 'dayjs' { + interface Dayjs { + calendar(referenceTime?: ConfigType, formats?: object): string + } +}