From 8bf984174968b40b93e30218808381a2a650e16c Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Thu, 13 Sep 2018 22:49:49 +1000 Subject: [PATCH 1/6] Add dayjs and update README --- README.md | 186 ++++++++++++++++++++++++++++++++++++++--- __tests__/index.js | 103 +++++++++++++++++++++-- lib/rules/methods.json | 20 ++--- package.json | 1 + screenshot.png | Bin 35322 -> 0 bytes 5 files changed, 281 insertions(+), 29 deletions(-) delete mode 100644 screenshot.png diff --git a/README.md b/README.md index 77a7ed1..a5723e5 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,17 @@ Problems with Moment.js: - Moment.js is mutable due to OOP APIs and non-pure functions, which causes bugs: https://github.com/moment/moment/blob/develop/src/test/moment/add_subtract.js#L244-L286 -Only using some simple functions from moment.js might be considered overkill, [date-fns](https://github.com/date-fns/date-fns) can be a good replacement in such situations. See https://github.com/moment/moment/issues/2373 for more ideas on why and how people switch from moment.js to date-fns. +Only using some simple functions from moment.js might be considered overkill, [date-fns](https://github.com/date-fns/date-fns) and [dayjs](https://github.com/iamkun/dayjs) can be good replacements in such situations. See https://github.com/moment/moment/issues/2373 for more ideas on why and how people switch from moment.js to other date libs. -Screenshot +## Comparison + +Let's take a look at date lib comparison in the following table: + +| Name | Size(gzip) | Tree-shaking | Popularity | Methods richness | Pattern | Timezone Support | Locale | +| --------- | ------------ | ------------ | ---------- | ---------------- | ---------- | --------------------- | ------ | +| Moment.js | 329K(69.6K) | No | 38k | High | OOP | Good(moment-timezone) | 123 | +| date-fns | 78.4k(13.4k) | Yes | 13k | High | Functional | not yet | 32 | +| dayjs | 6.5k | No | 14k | Medium | OOP | not yet | 23 | ## Voice of Developers @@ -131,6 +139,10 @@ moment("12-25-1995", "MM-DD-YYYY"); import parse from "date-fns/parse"; parse("12-25-1995", "MM-dd-yyyy", new Date()); // => "1995-12-24T13:00:00.000Z" + +// dayjs +dayjs("12-25-1995"); +// => "1995-12-24T13:00:00.000Z" ``` **[⬆ back to top](#quick-links)** @@ -148,6 +160,8 @@ moment("2010-10-20 4:30", "YYYY-MM-DD HH:mm"); import parse from "date-fns/parse"; parse("2010-10-20 4:30", "yyyy-MM-dd H:mm", new Date()); // => "2010-10-19T17:30:00.000Z" + +// dayjs ❌ not support custom format parse ``` **[⬆ back to top](#quick-links)** @@ -166,6 +180,8 @@ import parse from "date-fns/parse"; import fr from "date-fns/locale/fr"; parse("2012 mars", "yyyy MMMM", new Date(), { locale: fr }); // => "2012-02-29T13:00:00.000Z" + +// dayjs ❌ not support custom format parse ``` **[⬆ back to top](#quick-links)** @@ -188,6 +204,20 @@ new Date().getSeconds(); // => 49 new Date().getHours(); // => 19 + +// date-fns +import getSeconds from "date-fns/getSeconds"; +import getHours from "date-fns/getHours"; +getSeconds(new Date()); +// => 49 +getHours(new Date()); +// => 19 + +// dayjs +dayjs().second(); +// => 49 +dayjs().hour(); +// => 19 ``` Set the `Millisecond/Second/Minute/Hour` of the given date. @@ -204,6 +234,20 @@ new Date(new Date().setSeconds(30)); // => "2018-09-09T09:12:30.695Z" new Date(new Date().setHours(13)); // => "2018-09-09T03:12:49.695Z" + +// date-fns +import setSeconds from "date-fns/setSeconds"; +import setHours from "date-fns/setHours"; +setSeconds(new Date(), 30); +// => "2018-09-09T09:12:30.695Z" +setHours(new Date(), 13); +// => "2018-09-09T03:12:49.695Z" + +// dayjs +dayjs().set("second", 30); +// => "2018-09-09T09:12:30.695Z" +dayjs().set("hour", 13); +// => "2018-09-09T03:12:49.695Z" ``` **[⬆ back to top](#quick-links)** @@ -224,6 +268,20 @@ new Date().getDate(); // => 9 new Date().setDate(4); // => "2018-09-04T09:12:49.695Z" + +// date-fns +import getDate from "date-fns/getDate"; +import setDate from "date-fns/setDate"; +getDate(new Date()); +// => 9 +setDate(new Date(), 4); +// => "2018-09-04T09:12:49.695Z" + +// dayjs +dayjs().date(); +// => 9 +dayjs().set("date", 4); +// => "2018-09-04T09:12:49.695Z" ``` **[⬆ back to top](#quick-links)** @@ -235,15 +293,29 @@ Gets or sets the day of the week. ```js // Moment.js moment().day(); -// => 0 +// => 0 (Sunday) moment().day(-14); // => "2018-08-26T09:12:49.695Z" // Native new Date().getDay(); -// => 0 +// => 0 (Sunday) new Date().setDate(new Date().getDate() - 14); // => "2018-08-26T09:12:49.695Z" + +// date-fns +import getDay from "date-fns/getDay"; +import setDay from "date-fns/setDay"; +getDay(new Date()); +// => 0 (Sunday) +setDay(new Date(), -14); +// => "2018-08-26T09:12:49.695Z" + +// dayjs +dayjs().day(); +// => 0 (Sunday) +dayjs().set("day", -14); +// => "2018-08-26T09:12:49.695Z" ``` **[⬆ back to top](#quick-links)** @@ -261,11 +333,13 @@ moment().dayOfYear(256); // date-fns import getDayOfYear from "date-fns/getDayOfYear"; +import setDayOfYear from "date-fns/setDayOfYear"; getDayOfYear(new Date()); // => 252 -import setDayOfYear from "date-fns/setDayOfYear"; setDayOfYear(new Date(), 256); // => "2018-09-13T09:12:49.695Z" + +// dayjs ❌ not support day of year ``` **[⬆ back to top](#quick-links)** @@ -283,11 +357,18 @@ moment().week(24); // date-fns import getWeek from "date-fns/getWeek"; +import setWeek from "date-fns/setWeek"; getWeek(new Date()); // => 37 -import setWeek from "date-fns/setWeek"; setWeek(new Date(), 24); // => "2018-06-10T09:12:49.695Z" + +// dayjs ⚠️ requires plugin +import weekOfYear from "dayjs/plugin/weekOfYear"; +dayjs.extend(weekOfYear); +dayjs().week(); +// => 37 +// dayjs ❌ not support set week of year ``` **[⬆ back to top](#quick-links)** @@ -305,6 +386,10 @@ moment("2012-02", "YYYY-MM").daysInMonth(); import getDaysInMonth from "date-fns/getDaysInMonth"; getDaysInMonth(new Date(2012, 1)); // => 29 + +// dayjs +dayjs("2012-02").daysInMonth(); +// => 29 ``` **[⬆ back to top](#quick-links)** @@ -322,6 +407,8 @@ moment().isoWeeksInYear(); import getISOWeeksInYear from "date-fns/getISOWeeksInYear"; getISOWeeksInYear(new Date()); // => 52 + +// dayjs ❌ not support weeks in year ``` **[⬆ back to top](#quick-links)** @@ -345,6 +432,8 @@ moment.max(array.map(a => moment(a))); import max from "date-fns/max"; max(array); // => "2018-03-11T13:00:00.000Z" + +// dayjs ❌ not support maximum of the given dates ``` **[⬆ back to top](#quick-links)** @@ -368,6 +457,8 @@ moment.min(array.map(a => moment(a))); import min from "date-fns/min"; min(array); // => "2016-01-08T13:00:00.000Z" + +// dayjs ❌ not support minimum of the given dates ``` **[⬆ back to top](#quick-links)** @@ -387,6 +478,10 @@ moment().add(7, "days"); import addDays from "date-fns/addDays"; addDays(new Date(), 7); // => "2018-09-16T09:12:49.695Z" + +// dayjs +dayjs().add(7, "day"); +// => "2018-09-16T09:12:49.695Z" ``` **[⬆ back to top](#quick-links)** @@ -404,6 +499,10 @@ moment().subtract(7, "days"); import subDays from "date-fns/subDays"; subDays(new Date(), 7); // => "2018-09-02T09:12:49.695Z" + +// dayjs +dayjs().subtract(7, "day"); +// => "2018-09-02T09:12:49.695Z" ``` **[⬆ back to top](#quick-links)** @@ -421,6 +520,10 @@ moment().startOf("month"); import startOfMonth from "date-fns/startOfMonth"; startOfMonth(new Date()); // => "2018-08-31T14:00:00.000Z" + +// dayjs +dayjs().startOf("month"); +// => "2018-08-31T14:00:00.000Z" ``` **[⬆ back to top](#quick-links)** @@ -438,6 +541,10 @@ moment().endOf("day"); import endOfDay from "date-fns/endOfDay"; endOfDay(new Date()); // => "2018-09-09T13:59:59.999Z" + +// dayjs +dayjs().endOf("day"); +// => "2018-09-09T13:59:59.999Z" ``` **[⬆ back to top](#quick-links)** @@ -461,6 +568,12 @@ format(new Date(), "eeee, MMMM do YYYY, h:mm:ss aa"); // => "Sunday, September 9th 2018, 7:12:49 PM" format(new Date(), "eee, ha"); // => "Sun, 7PM" + +// dayjs +dayjs().format("dddd, MMMM D YYYY, h:mm:ss A"); +// => "Sunday, September 9 2018, 7:12:49 PM" ⚠️ not support 9th +dayjs().format("ddd, hA"); +// => "Sun, 7PM" ``` **[⬆ back to top](#quick-links)** @@ -471,13 +584,20 @@ Return time from now. ```js // Moment.js -moment([2018, 8, 9]).fromNow(); -// => "about 4 hours ago" +moment(1536484369695).fromNow(); +// => "4 days ago" // date-fns import formatDistance from "date-fns/formatDistance"; -formatDistance(new Date(2018, 8, 9), new Date(), { addSuffix: true }); -// => "4 hours ago" +formatDistance(new Date(1536484369695), new Date(), { addSuffix: true }); +// => "4 days ago" + +// dayjs ⚠️ requires plugin +import RelativeTime from "dayjs/plugin/RelativeTime"; +dayjs.extend(RelativeTime); + +dayjs(1536484369695).fromNow(); +// => "5 days ago" ⚠️ the rounding method of this plugin is different from moment.js and date-fns, use with care. ``` **[⬆ back to top](#quick-links)** @@ -495,6 +615,12 @@ moment([2007, 0, 27]).to(moment([2007, 0, 29])); import formatDistance from "date-fns/formatDistance"; formatDistance(new Date(2007, 0, 27), new Date(2007, 0, 29)); // => "2 days" + +// dayjs ⚠️ requires plugin +import RelativeTime from "dayjs/plugin/RelativeTime"; +dayjs.extend(RelativeTime); +dayjs("2007-01-27").to(dayjs("2007-01-29")); +// => "in 2 days" ``` **[⬆ back to top](#quick-links)** @@ -517,6 +643,12 @@ differenceInMilliseconds(new Date(2007, 0, 27), new Date(2007, 0, 29)); import differenceInDays from "date-fns/differenceInDays"; differenceInDays(new Date(2007, 0, 27), new Date(2007, 0, 29)); // => -2 + +// dayjs +dayjs("2007-01-27").diff(dayjs("2007-01-29"), "milliseconds"); +// => -172800000 +dayjs("2007-01-27").diff(dayjs("2007-01-29"), "days"); +// => -2 ``` **[⬆ back to top](#quick-links)** @@ -536,6 +668,10 @@ moment("2010-10-20").isBefore("2010-10-21"); import isBefore from "date-fns/isBefore"; isBefore(new Date(2010, 9, 20), new Date(2010, 9, 21)); // => true + +// dayjs +dayjs("2010-10-20").isBefore("2010-10-21"); +// => true ``` **[⬆ back to top](#quick-links)** @@ -550,13 +686,25 @@ moment("2010-10-20").isSame("2010-10-21"); // => false moment("2010-10-20").isSame("2010-10-20"); // => true +moment("2010-10-20").isSame("2010-10-21", "month"); +// => true // date-fns import isSameDay from "date-fns/isSameDay"; +import isSameMonth from "date-fns/isSameMonth"; isSameDay(new Date(2010, 9, 20), new Date(2010, 9, 21)); // => false isSameDay(new Date(2010, 9, 20), new Date(2010, 9, 20)); // => true +isSameMonth(new Date(2010, 9, 20), new Date(2010, 9, 21)); +// => true + +// dayjs +dayjs("2010-10-20").isSame("2010-10-21"); +// => false +dayjs("2010-10-20").isSame("2010-10-20"); +// => true +// dayjs ❌ not support is same month ``` **[⬆ back to top](#quick-links)** @@ -574,6 +722,10 @@ moment("2010-10-20").isAfter("2010-10-19"); import isAfter from "date-fns/isAfter"; isAfter(new Date(2010, 9, 20), new Date(2010, 9, 19)); // => true + +// dayjs +dayjs("2010-10-20").isAfter("2010-10-19"); +// => true ``` **[⬆ back to top](#quick-links)** @@ -594,6 +746,12 @@ isWithinInterval(new Date(2010, 9, 20), { end: new Date(2010, 9, 25) }); // => true + +// dayjs ⚠️ requires plugin +import IsBetween from "dayjs/plugin/IsBetween"; +dayjs.extend(IsBetween); +dayjs("2010-10-20").isBetween("2010-10-19", "2010-10-25"); +// => true ``` **[⬆ back to top](#quick-links)** @@ -611,6 +769,12 @@ moment([2000]).isLeapYear(); import isLeapYear from "date-fns/isLeapYear"; isLeapYear(new Date(2000, 0, 1)); // => true + +// dayjs ⚠️ requires plugin +import IsLeapYear from "dayjs/plugin/IsLeapYear"; +dayjs.extend(IsLeapYear); +dayjs("2000").isLeapYear(); +// => true ``` **[⬆ back to top](#quick-links)** @@ -628,6 +792,8 @@ moment.isDate(new Date()); import isDate from "date-fns/isDate"; isDate(new Date()); // => true + +// dayjs ❌ not support is date ``` **[⬆ back to top](#quick-links)** diff --git a/__tests__/index.js b/__tests__/index.js index 02d8da9..9e7900c 100644 --- a/__tests__/index.js +++ b/__tests__/index.js @@ -1,6 +1,15 @@ const moment = require('moment'); const date = require('date-fns'); const fr = require('date-fns/locale/fr'); +const dayjs = require('dayjs'); +const RelativeTime = require('dayjs/plugin/RelativeTime'); // load on demand +const weekOfYear = require('dayjs/plugin/weekOfYear'); // load on demand +const IsBetween = require('dayjs/plugin/IsBetween'); // load on demand +const IsLeapYear = require('dayjs/plugin/IsLeapYear'); // load on demand +dayjs.extend(RelativeTime); +dayjs.extend(weekOfYear); +dayjs.extend(IsBetween); +dayjs.extend(IsLeapYear); const time = 1536484369695; @@ -8,7 +17,9 @@ describe('Parse', () => { it('String + Date Format', () => { const m = moment('12-25-1995', 'MM-DD-YYYY'); const d = date.parse('12-25-1995', 'MM-dd-yyyy', new Date()); + const day = dayjs('12-25-1995'); expect(m.valueOf()).toBe(d.getTime()); + expect(m.valueOf()).toBe(day.valueOf()); }); it('String + Time Format', () => { const m = moment('2010-10-20 4:30', 'YYYY-MM-DD HH:mm'); @@ -25,56 +36,96 @@ describe('Parse', () => { describe('Get + Set', () => { it('get Second', () => { const m = moment(time).seconds(); - const d = new Date(time).getSeconds(); + const n = new Date(time).getSeconds(); + const d = date.getSeconds(new Date(time)); + const day = dayjs(time).second(); + expect(m).toBe(n); expect(m).toBe(d); + expect(m).toBe(day); }); it('set Second', () => { const m = moment(time) .seconds(30) .valueOf(); - const d = new Date(time).setSeconds(30); + const n = new Date(time).setSeconds(30); + const d = date.setSeconds(new Date(time), 30).getTime(); + const day = dayjs(time) + .set('second', 30) + .valueOf(); + expect(m).toBe(n); expect(m).toBe(d); + expect(m).toBe(day); }); it('get Hour', () => { const m = moment(time).hours(); - const d = new Date(time).getHours(); + const n = new Date(time).getHours(); + const d = date.getHours(new Date(time)); + const day = dayjs(time).hour(); + expect(m).toBe(n); expect(m).toBe(d); + expect(m).toBe(day); }); it('set Hour', () => { const m = moment(time) .hour(13) .valueOf(); - const d = new Date(time).setHours(13); + const n = new Date(time).setHours(13); + const d = date.setHours(new Date(time), 13).getTime(); + const day = dayjs(time) + .set('hour', 13) + .valueOf(); + expect(m).toBe(n); expect(m).toBe(d); + expect(m).toBe(day); }); it('get Date of Month', () => { const m = moment(time).date(); - const d = new Date(time).getDate(); + const n = new Date(time).getDate(); + const d = date.getDate(new Date(time)); + const day = dayjs(time).date(); + expect(m).toBe(n); expect(m).toBe(d); + expect(m).toBe(day); }); it('set Date of Month', () => { const m = moment(time) .date(4) .valueOf(); - const d = new Date(time).setDate(4); + const n = new Date(time).setDate(4); + const d = date.setDate(new Date(time), 4).getTime(); + const day = dayjs(time) + .set('date', 4) + .valueOf(); + expect(m).toBe(n); expect(m).toBe(d); + expect(m).toBe(day); }); it('get Day of Week', () => { const m = moment(time).day(); - const d = new Date(time).getDay(); + const n = new Date(time).getDay(); + const d = date.getDay(new Date(time)); + const day = dayjs(time).day(); + expect(m).toBe(n); expect(m).toBe(d); + expect(m).toBe(day); }); it('set Day of Week', () => { const m = moment(time) .day(-14) .valueOf(); - const d = new Date(time).setDate(new Date(time).getDate() - 14); + const n = new Date(time).setDate(new Date(time).getDate() - 14); + const d = date.setDay(new Date(time), -14).getTime(); + const day = dayjs(time) + .set('day', -14) + .valueOf(); + expect(m).toBe(n); expect(m).toBe(d); + expect(m).toBe(day); }); it('get Day of Year', () => { @@ -94,7 +145,9 @@ describe('Get + Set', () => { it('get Week of Year', () => { const m = moment(time).week(); const d = date.getWeek(new Date(time)); + const day = dayjs(time).week(); // plugin expect(m).toBe(d); + expect(m).toBe(day); }); it('set Week of Year', () => { @@ -108,7 +161,9 @@ describe('Get + Set', () => { it('Days in Month', () => { const m = moment('2012-02', 'YYYY-MM').daysInMonth(); const d = date.getDaysInMonth(new Date(2012, 1)); + const day = dayjs('2012-02').daysInMonth(); expect(m).toBe(d); + expect(m).toBe(day); }); it('get Weeks In Year', () => { @@ -148,25 +203,33 @@ describe('Manipulate', () => { it('Add', () => { const m = moment(time).add(7, 'days'); const d = date.addDays(new Date(time), 7); + const day = dayjs(time).add(7, 'day'); expect(m.valueOf()).toBe(d.getTime()); + expect(m.valueOf()).toBe(day.valueOf()); }); it('Subtract', () => { const m = moment(time).subtract(7, 'days'); const d = date.subDays(new Date(time), 7); + const day = dayjs(time).subtract(7, 'day'); expect(m.valueOf()).toBe(d.getTime()); + expect(m.valueOf()).toBe(day.valueOf()); }); it('Start of Time', () => { const m = moment(time).startOf('month'); const d = date.startOfMonth(new Date(time)); + const day = dayjs(time).startOf('month'); expect(m.valueOf()).toBe(d.getTime()); + expect(m.valueOf()).toBe(day.valueOf()); }); it('End of Time', () => { const m = moment(time).endOf('day'); const d = date.endOfDay(new Date(time)); + const day = dayjs(time).endOf('day'); expect(m.valueOf()).toBe(d.getTime()); + expect(m.valueOf()).toBe(day.valueOf()); }); }); @@ -174,11 +237,15 @@ describe('Display', () => { it('Format', () => { const m = moment(time).format('dddd, MMMM Do YYYY, h:mm:ss A'); const d = date.format(new Date(time), 'eeee, MMMM do YYYY, h:mm:ss aa'); + const day = dayjs(time).format('dddd, MMMM D YYYY, h:mm:ss A'); expect(m).toBe(d); + expect(moment(time).format('dddd, MMMM D YYYY, h:mm:ss A')).toBe(day); const m2 = moment(time).format('ddd, hA'); const d2 = date.format(new Date(time), 'eee, ha'); + const day2 = dayjs(time).format('ddd, hA'); expect(m2).toBe(d2); + expect(m2).toBe(day2); }); it('Time from now', () => { @@ -186,13 +253,17 @@ describe('Display', () => { const d = date.formatDistance(new Date(time), new Date(), { addSuffix: true, }); - expect(d).toContain(m); + const day = dayjs(time).fromNow(); // plugin + expect(m).toBe(d); + expect(moment().fromNow()).toBe(dayjs().fromNow()); }); it('Time from X', () => { const m = moment([2007, 0, 27]).to(moment([2007, 0, 29])); const d = date.formatDistance(new Date(2007, 0, 27), new Date(2007, 0, 29)); + const day = dayjs('2007-01-27').to(dayjs('2007-01-29')); expect(m).toContain(d); + expect(m).toBe(day); }); it('Difference', () => { @@ -201,14 +272,18 @@ describe('Display', () => { new Date(2007, 0, 27), new Date(2007, 0, 29) ); + const day = dayjs('2007-01-27').diff(dayjs('2007-01-29'), 'milliseconds'); expect(m).toBe(d); + expect(m).toBe(day); const m2 = moment([2007, 0, 27]).diff(moment([2007, 0, 29]), 'days'); const d2 = date.differenceInDays( new Date(2007, 0, 27), new Date(2007, 0, 29) ); + const day2 = dayjs('2007-01-27').diff(dayjs('2007-01-29'), 'days'); expect(m2).toBe(d2); + expect(m2).toBe(day2); }); }); @@ -216,8 +291,10 @@ describe('Query', () => { it('Is Before', () => { const m = moment('2010-10-20').isBefore('2010-10-21'); const d = date.isBefore(new Date(2010, 9, 20), new Date(2010, 9, 21)); + const day = dayjs('2010-10-20').isBefore('2010-10-21'); //plugin expect(m).toBeTruthy(); expect(d).toBeTruthy(); + expect(day).toBeTruthy(); }); it('Is Same', () => { @@ -225,6 +302,7 @@ describe('Query', () => { expect( date.isSameDay(new Date(2010, 9, 20), new Date(2010, 9, 21)) ).toBeFalsy(); + expect(dayjs('2010-10-20').isSame('2010-10-21')).toBeFalsy(); expect(moment('2010-10-20').isSame('2010-10-21', 'month')).toBeTruthy(); expect( @@ -235,8 +313,10 @@ describe('Query', () => { it('Is After', () => { const m = moment('2010-10-20').isAfter('2010-10-19'); const d = date.isAfter(new Date(2010, 9, 20), new Date(2010, 9, 19)); + const day = dayjs('2010-10-20').isAfter('2010-10-19'); expect(m).toBeTruthy(); expect(d).toBeTruthy(); + expect(day).toBeTruthy(); }); it('Is Between', () => { @@ -245,18 +325,23 @@ describe('Query', () => { start: new Date(2010, 9, 19), end: new Date(2010, 9, 25), }); + const day = dayjs('2010-10-20').isBetween('2010-10-19', '2010-10-25'); //plugin + expect(m).toBeTruthy(); expect(d).toBeTruthy(); + expect(day).toBeTruthy(); }); it('Is Leap Year', () => { expect(moment([2000]).isLeapYear()).toBeTruthy(); expect(date.isLeapYear(new Date(2000, 0, 1))).toBeTruthy(); expect(date.isLeapYear(new Date(2001, 0, 1))).toBeFalsy(); + expect(dayjs('2000').isLeapYear()).toBeTruthy(); }); it('Is a Date', () => { expect(moment.isDate(new Date())).toBeTruthy(); expect(date.isDate(new Date())).toBeTruthy(); + expect(dayjs.isDayjs(dayjs())).toBeTruthy(); }); }); diff --git a/lib/rules/methods.json b/lib/rules/methods.json index 1d8ed38..7fe26d0 100644 --- a/lib/rules/methods.json +++ b/lib/rules/methods.json @@ -27,19 +27,19 @@ "alternative": "date-fns min(date)" }, "add": { - "alternative": "date-fns addDays(date, amount)" + "alternative": "date-fns addDays(date, amount) or dayjs().add(number, unit)" }, "subtract": { - "alternative": "date-fns subDays(date, amount)" + "alternative": "date-fns subDays(date, amount) or dayjs().subtract(number, unit)" }, "startOf": { - "alternative": "date-fns startOfMonth(date)" + "alternative": "date-fns startOfMonth(date) or dayjs().startOf(unit)" }, "endOf": { - "alternative": "date-fns endOfDay(date)" + "alternative": "date-fns endOfDay(date) or dayjs().endOf(unit)" }, "format": { - "alternative": "date-fns format(date, format)" + "alternative": "date-fns format(date, format) or dayjs().format()" }, "fromNow": { "alternative": "date-fns formatDistance(date, baseDate)" @@ -48,19 +48,19 @@ "alternative": "date-fns formatDistance(date, baseDate)" }, "diff": { - "alternative": "date-fns differenceInMilliseconds(dateLeft, dateRight)" + "alternative": "date-fns differenceInMilliseconds(dateLeft, dateRight) or dayjs().diff()" }, "daysInMonth": { - "alternative": "date-fns getDaysInMonth(date)" + "alternative": "date-fns getDaysInMonth(date) or dayjs().daysInMonth();" }, "isBefore": { - "alternative": "date-fns isBefore(date, dateToCompare)" + "alternative": "date-fns isBefore(date, dateToCompare) or dayjs().isBefore()" }, "isSame": { - "alternative": "date-fns isSameMonth(dateLeft, dateRight)" + "alternative": "date-fns isSameMonth(dateLeft, dateRight) or dayjs().isSame()" }, "isAfter": { - "alternative": "date-fns isAfter(date, dateToCompare)" + "alternative": "date-fns isAfter(date, dateToCompare) or dayjs().isAfter()" }, "isBetween": { "alternative": "date-fns isWithinInterval(date, interval)" diff --git a/package.json b/package.json index 722b044..ce5d446 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "babel-eslint": "^9.0.0", "coveralls": "^3.0.2", "date-fns": "^2.0.0-alpha.16", + "dayjs": "^1.7.5", "eslint": "^5.5.0", "husky": "^0.14.3", "jest": "^23.5.0", diff --git a/screenshot.png b/screenshot.png deleted file mode 100644 index 1c4e82880f98626207233e69c6a9deb17d8b0b51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35322 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

-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 Date: Thu, 13 Sep 2018 23:17:54 +1000 Subject: [PATCH 2/6] update readme by fixing typo --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a5723e5..3e7c166 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ import parse from "date-fns/parse"; parse("2010-10-20 4:30", "yyyy-MM-dd H:mm", new Date()); // => "2010-10-19T17:30:00.000Z" -// dayjs ❌ not support custom format parse +// dayjs ❌ does not support custom format parse ``` **[⬆ back to top](#quick-links)** @@ -181,7 +181,7 @@ import fr from "date-fns/locale/fr"; parse("2012 mars", "yyyy MMMM", new Date(), { locale: fr }); // => "2012-02-29T13:00:00.000Z" -// dayjs ❌ not support custom format parse +// dayjs ❌ does not support custom format parse ``` **[⬆ back to top](#quick-links)** @@ -339,7 +339,7 @@ getDayOfYear(new Date()); setDayOfYear(new Date(), 256); // => "2018-09-13T09:12:49.695Z" -// dayjs ❌ not support day of year +// dayjs ❌ does not support day of year ``` **[⬆ back to top](#quick-links)** @@ -368,7 +368,7 @@ import weekOfYear from "dayjs/plugin/weekOfYear"; dayjs.extend(weekOfYear); dayjs().week(); // => 37 -// dayjs ❌ not support set week of year +// dayjs ❌ does not support set week of year ``` **[⬆ back to top](#quick-links)** @@ -408,7 +408,7 @@ import getISOWeeksInYear from "date-fns/getISOWeeksInYear"; getISOWeeksInYear(new Date()); // => 52 -// dayjs ❌ not support weeks in year +// dayjs ❌ does not support weeks in the year ``` **[⬆ back to top](#quick-links)** @@ -433,7 +433,7 @@ import max from "date-fns/max"; max(array); // => "2018-03-11T13:00:00.000Z" -// dayjs ❌ not support maximum of the given dates +// dayjs ❌ does not support the maximum of the given dates ``` **[⬆ back to top](#quick-links)** @@ -458,7 +458,7 @@ import min from "date-fns/min"; min(array); // => "2016-01-08T13:00:00.000Z" -// dayjs ❌ not support minimum of the given dates +// dayjs ❌ does not support the minimum of the given dates ``` **[⬆ back to top](#quick-links)** @@ -704,7 +704,7 @@ dayjs("2010-10-20").isSame("2010-10-21"); // => false dayjs("2010-10-20").isSame("2010-10-20"); // => true -// dayjs ❌ not support is same month +// dayjs ❌ does not support is same month ``` **[⬆ back to top](#quick-links)** @@ -793,7 +793,7 @@ import isDate from "date-fns/isDate"; isDate(new Date()); // => true -// dayjs ❌ not support is date +// dayjs ❌ does not support is date ``` **[⬆ back to top](#quick-links)** From 96cda765789bd7bca8f63d9e2271cc85943591f5 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Thu, 13 Sep 2018 23:21:30 +1000 Subject: [PATCH 3/6] fix test --- lib/__tests__/index.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/__tests__/index.js b/lib/__tests__/index.js index 2abfc43..f5464f2 100644 --- a/lib/__tests__/index.js +++ b/lib/__tests__/index.js @@ -135,11 +135,12 @@ describe('ESLint plugin', () => { code: "const m = moment('2010-10-20').isAfter('2010-10-19')", errors: [ { - message: 'Consider using date-fns isAfter(date, dateToCompare)', - type: 'CallExpression', - }, - ], - }, - ], + message: + "Consider using date-fns isAfter(date, dateToCompare) or dayjs().isAfter()", + type: "CallExpression" + } + ] + } + ] }); }); From 1d145fa07190a32e88306bc89f07b6ce8ea45635 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Thu, 13 Sep 2018 23:32:10 +1000 Subject: [PATCH 4/6] fix case of dayjs plugin --- README.md | 16 ++++++++-------- __tests__/index.js | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 3e7c166..91eea39 100644 --- a/README.md +++ b/README.md @@ -593,8 +593,8 @@ formatDistance(new Date(1536484369695), new Date(), { addSuffix: true }); // => "4 days ago" // dayjs ⚠️ requires plugin -import RelativeTime from "dayjs/plugin/RelativeTime"; -dayjs.extend(RelativeTime); +import relativeTime from "dayjs/plugin/relativeTime"; +dayjs.extend(relativeTime); dayjs(1536484369695).fromNow(); // => "5 days ago" ⚠️ the rounding method of this plugin is different from moment.js and date-fns, use with care. @@ -617,8 +617,8 @@ formatDistance(new Date(2007, 0, 27), new Date(2007, 0, 29)); // => "2 days" // dayjs ⚠️ requires plugin -import RelativeTime from "dayjs/plugin/RelativeTime"; -dayjs.extend(RelativeTime); +import relativeTime from "dayjs/plugin/relativeTime"; +dayjs.extend(relativeTime); dayjs("2007-01-27").to(dayjs("2007-01-29")); // => "in 2 days" ``` @@ -748,8 +748,8 @@ isWithinInterval(new Date(2010, 9, 20), { // => true // dayjs ⚠️ requires plugin -import IsBetween from "dayjs/plugin/IsBetween"; -dayjs.extend(IsBetween); +import isBetween from "dayjs/plugin/isBetween"; +dayjs.extend(isBetween); dayjs("2010-10-20").isBetween("2010-10-19", "2010-10-25"); // => true ``` @@ -771,8 +771,8 @@ isLeapYear(new Date(2000, 0, 1)); // => true // dayjs ⚠️ requires plugin -import IsLeapYear from "dayjs/plugin/IsLeapYear"; -dayjs.extend(IsLeapYear); +import isLeapYear from "dayjs/plugin/isLeapYear"; +dayjs.extend(isLeapYear); dayjs("2000").isLeapYear(); // => true ``` diff --git a/__tests__/index.js b/__tests__/index.js index 9e7900c..f17cd5b 100644 --- a/__tests__/index.js +++ b/__tests__/index.js @@ -2,14 +2,14 @@ const moment = require('moment'); const date = require('date-fns'); const fr = require('date-fns/locale/fr'); const dayjs = require('dayjs'); -const RelativeTime = require('dayjs/plugin/RelativeTime'); // load on demand +const relativeTime = require('dayjs/plugin/relativeTime'); // load on demand const weekOfYear = require('dayjs/plugin/weekOfYear'); // load on demand -const IsBetween = require('dayjs/plugin/IsBetween'); // load on demand -const IsLeapYear = require('dayjs/plugin/IsLeapYear'); // load on demand -dayjs.extend(RelativeTime); +const isBetween = require('dayjs/plugin/isBetween'); // load on demand +const isLeapYear = require('dayjs/plugin/isLeapYear'); // load on demand +dayjs.extend(relativeTime); dayjs.extend(weekOfYear); -dayjs.extend(IsBetween); -dayjs.extend(IsLeapYear); +dayjs.extend(isBetween); +dayjs.extend(isLeapYear); const time = 1536484369695; From 5e547c65fa4629863483eeee25f848c88dd98373 Mon Sep 17 00:00:00 2001 From: Andrew Yang Date: Thu, 13 Sep 2018 23:43:04 +1000 Subject: [PATCH 5/6] add plugin name --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 91eea39..469dba9 100644 --- a/README.md +++ b/README.md @@ -363,7 +363,7 @@ getWeek(new Date()); setWeek(new Date(), 24); // => "2018-06-10T09:12:49.695Z" -// dayjs ⚠️ requires plugin +// dayjs ⚠️ requires weekOfYear plugin import weekOfYear from "dayjs/plugin/weekOfYear"; dayjs.extend(weekOfYear); dayjs().week(); @@ -592,7 +592,7 @@ import formatDistance from "date-fns/formatDistance"; formatDistance(new Date(1536484369695), new Date(), { addSuffix: true }); // => "4 days ago" -// dayjs ⚠️ requires plugin +// dayjs ⚠️ requires relativeTime plugin import relativeTime from "dayjs/plugin/relativeTime"; dayjs.extend(relativeTime); @@ -616,7 +616,7 @@ import formatDistance from "date-fns/formatDistance"; formatDistance(new Date(2007, 0, 27), new Date(2007, 0, 29)); // => "2 days" -// dayjs ⚠️ requires plugin +// dayjs ⚠️ requires relativeTime plugin import relativeTime from "dayjs/plugin/relativeTime"; dayjs.extend(relativeTime); dayjs("2007-01-27").to(dayjs("2007-01-29")); @@ -747,7 +747,7 @@ isWithinInterval(new Date(2010, 9, 20), { }); // => true -// dayjs ⚠️ requires plugin +// dayjs ⚠️ requires isBetween plugin import isBetween from "dayjs/plugin/isBetween"; dayjs.extend(isBetween); dayjs("2010-10-20").isBetween("2010-10-19", "2010-10-25"); @@ -770,7 +770,7 @@ import isLeapYear from "date-fns/isLeapYear"; isLeapYear(new Date(2000, 0, 1)); // => true -// dayjs ⚠️ requires plugin +// dayjs ⚠️ requires isLeapYear plugin import isLeapYear from "dayjs/plugin/isLeapYear"; dayjs.extend(isLeapYear); dayjs("2000").isLeapYear(); From 0d21a22b4cdbfcc1a82c83786885d44c40329a13 Mon Sep 17 00:00:00 2001 From: Robert Chang Date: Fri, 14 Sep 2018 00:20:30 +1000 Subject: [PATCH 6/6] prettier code --- lib/__tests__/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/__tests__/index.js b/lib/__tests__/index.js index f5464f2..1252391 100644 --- a/lib/__tests__/index.js +++ b/lib/__tests__/index.js @@ -136,11 +136,11 @@ describe('ESLint plugin', () => { errors: [ { message: - "Consider using date-fns isAfter(date, dateToCompare) or dayjs().isAfter()", - type: "CallExpression" - } - ] - } - ] + 'Consider using date-fns isAfter(date, dateToCompare) or dayjs().isAfter()', + type: 'CallExpression', + }, + ], + }, + ], }); });