dayjs icon indicating copy to clipboard operation
dayjs copied to clipboard

dayjs('2020-10-01').add(dayjs.duration(1, 'months')) not returns dayjs('2020-11-01')

Open chimerast opened this issue 4 years ago • 3 comments
trafficstars

Describe the bug dayjs.duration(1, 'months') is converted to dayjs.duration(30, 'days') internally by duration plugin. so dayjs('2020-10-01').add(dayjs.duration(1, 'months')) returns dayjs('2020-10-31')

Expected behavior dayjs('2020-10-01').add(dayjs.duration(1, 'months')) should returns dayjs('2020-11-01')

Information

  • Day.js Version: 1.10.5
  • OS: macOS 11.4
  • Browser: Chrome 91
  • Time zone: GMT+09:00 JST

chimerast avatar Jun 01 '21 15:06 chimerast

To reproduce

diff --git a/test/plugin/duration.test.js b/test/plugin/duration.test.js
index cca1a82..57456af 100644
--- a/test/plugin/duration.test.js
+++ b/test/plugin/duration.test.js
@@ -174,8 +174,8 @@ describe('Add', () => {

 test('Add duration', () => {
   const a = dayjs('2020-10-01')
-  const days = dayjs.duration(2, 'days')
-  expect(a.add(days).format('YYYY-MM-DD')).toBe('2020-10-03')
+  const days = dayjs.duration(1, 'months')
+  expect(a.add(days).format('YYYY-MM-DD')).toBe('2020-11-01')
 })

 describe('Subtract', () => {

Results

  ● Add duration

    expect(received).toBe(expected) // Object.is equality

    Expected value to be:
      "2020-11-01"
    Received:
      "2020-10-31"

      176 |   const a = dayjs('2020-10-01')
      177 |   const days = dayjs.duration(1, 'months')
    > 178 |   expect(a.add(days).format('YYYY-MM-DD')).toBe('2020-11-01')
      179 | })
      180 |
      181 | describe('Subtract', () => {

      at Object.<anonymous> (test/plugin/duration.test.js:178:44)

chimerast avatar Jun 01 '21 15:06 chimerast

That's because:

"Durations do not have a defined beginning and end date. They are contextless.

A duration is conceptually more similar to '2 hours' than to 'between 2 and 4 pm today'. As such, they are not a good solution to converting between units that depend on context."

The idea of Duration is simple. What's a month? 30 days. What's a year? 365 days. That's it. You probably want a more precise library/plugin.

toiletpatrol avatar Aug 27 '21 11:08 toiletpatrol

I don't think this issue is relevant any longer. Both of these two tests succeeds on my machine.

dayjs.tz.setDefault("Asia/Tokyo");
assert.equal(dayjs("2020-10-01").add(1, "month").isSame(dayjs("2020-11-01"), "day"), true);
assert.equal(dayjs("2020-10-01").add(dayjs.duration(1, "months")).isSame(dayjs("2020-11-01"), "day"), true);

Magnuti avatar May 30 '24 17:05 Magnuti