Repository: iamkun/dayjs
Pull request #2362 (2023-06-30 21:41:31)

fix: duration plugin - MILLISECONDS_A_MONTH const calculation
`MILLISECONDS_A_DAY * 30` will generate wrong value for a larger diffs, it's generating wrong durations for months

it should be either `MILLISECONDS_A_DAY * 30.416666666666668` (365 / 12) or `MILLISECONDS_A_YEAR / 12`



sanjaynishad: actually one more fixes required with `parseFromMilliseconds`

need to check if duration ms is having leap year, then need to recalculate `MILLISECONDS_A_YEAR` and `MILLISECONDS_A_MONTH`

something like 

```
parseFromMilliseconds() {
    let { $ms } = this
    let msInYear = MILLISECONDS_A_YEAR;
    let msInMonth = MILLISECONDS_A_MONTH;
    let years = roundNumber($ms / MILLISECONDS_A_YEAR);
    if (roundNumber(years / 4)) {
      msInYear = MILLISECONDS_A_DAY * 365.25;
      msInMonth = msInYear / 12;
    }

    this.$d.years = roundNumber($ms / msInYear)
    $ms %= msInYear
    this.$d.months = roundNumber($ms / msInMonth)
    $ms %= msInMonth
    this.$d.days = roundNumber($ms / MILLISECONDS_A_DAY)
    $ms %= MILLISECONDS_A_DAY
```

iamkun: can you fix the CI as well pls?
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/iamkun/dayjs/pull/2362?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#2362](https://app.codecov.io/gh/iamkun/dayjs/pull/2362?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (57cc7e0) into [dev](https://app.codecov.io/gh/iamkun/dayjs/commit/df49762140dc229924bb59a7ca4f9c3d84f80ec0?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (df49762) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff            @@
##               dev     #2362   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          183       183           
  Lines         2111      2198   +87     
  Branches       555       593   +38     
=========================================
+ Hits          2111      2198   +87     
```


| [Impacted Files](https://app.codecov.io/gh/iamkun/dayjs/pull/2362?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [src/index.js](https://app.codecov.io/gh/iamkun/dayjs/pull/2362?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL2luZGV4Lmpz) | `100.00% <100.00%> (ø)` | |
| [src/plugin/duration/index.js](https://app.codecov.io/gh/iamkun/dayjs/pull/2362?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL3BsdWdpbi9kdXJhdGlvbi9pbmRleC5qcw==) | `100.00% <100.00%> (ø)` | |
| [src/plugin/minMax/index.js](https://app.codecov.io/gh/iamkun/dayjs/pull/2362?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL3BsdWdpbi9taW5NYXgvaW5kZXguanM=) | `100.00% <100.00%> (ø)` | |
| [src/plugin/objectSupport/index.js](https://app.codecov.io/gh/iamkun/dayjs/pull/2362?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-c3JjL3BsdWdpbi9vYmplY3RTdXBwb3J0L2luZGV4Lmpz) | `100.00% <100.00%> (ø)` | |



Patch:
diff --git a/src/plugin/duration/index.js b/src/plugin/duration/index.js
index d7adf75..0000470 100644
--- a/src/plugin/duration/index.js
+++ b/src/plugin/duration/index.js
@@ -8,7 +8,7 @@ import {
 } from '../../constant'
 
 const MILLISECONDS_A_YEAR = MILLISECONDS_A_DAY * 365
-const MILLISECONDS_A_MONTH = MILLISECONDS_A_DAY * 30
+const MILLISECONDS_A_MONTH = MILLISECONDS_A_YEAR / 12
 
 const durationRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/
 


Test patch:
diff --git a/test/plugin/duration.test.js b/test/plugin/duration.test.js
index eec20b1..7c6c699 100644
--- a/test/plugin/duration.test.js
+++ b/test/plugin/duration.test.js
@@ -92,8 +92,9 @@ describe('Parse ISO string', () => {
   it('ISO string with week', () => {
     const d = dayjs.duration('P2M3W4D')
     expect(d.toISOString()).toBe('P2M25D')
-    expect(d.asDays()).toBe(85) // moment 85, count 2M as 61 days
-    expect(d.asWeeks()).toBe(12.142857142857142) // moment 12.285714285714286
+    expect(d.asDays()).toBe(85.83333333333333) // moment 86, count 2M as 61 days
+    expect(d.asWeeks()).toBe(12.261904761904763) // moment 12.285714285714286
+    expect(d.asMonths()).toBe(2.8219178082191783) // moment 2.8213721020965523
   })
   it('Invalid ISO string', () => {
     expect(dayjs.duration('Invalid').toISOString()).toBe('P0D')