dayjs
dayjs copied to clipboard
relativeTime outputs wrong amount of months
Describe the bug When you put in custom thresholds for relativeTime to output everything up to 9999 months as months, and enter a duration longer than 36 months, some months get lost.
Expected behavior Output of correct amount of month
Information
- dayjs 1.9.3
- Windows
- Chrome
- CEST
I created a fiddle here https://jsfiddle.net/sy50xg2e/1/
Details
const config = {
thresholds: [
{l: 's', r: 59, d: 'second'},
{l: 'm', r: 59},
{l: 'mm', r: 59, d: 'minute'},
{l: 'h', r: 23},
{l: 'hh', r: 23, d: 'hour'},
{l: 'd', r: 29},
{l: 'dd', r: 29, d: 'day'},
{l: 'M', r: 1},
{l: 'MM', r: 9999, d: 'month'}
// {l: 'y', r: 1},
// {l: 'yy', r: 9999, d: 'year'}
]
};
dayjs.extend(dayjs_plugin_relativeTime, config)
dayjs.extend(dayjs_plugin_duration)
console.log(dayjs.duration(36, "month").humanize());
console.log(dayjs.duration(37, "month").humanize());
console.log(dayjs.duration(38, "month").humanize());
console.log(dayjs.duration(9999, "month").humanize());
The output is:
"36 months"
"36 months"
"37 months"
"9855 months"
I'd expect, 36, 37, 38, 9999.
We might have to re-think about the implementation of the duration plugin.
It is not safe just to store duration in ms, cause not all days in a month is 30, and not all dayjs in a year is 365.
That's why this error happened.
Below is a test case that shows that the results of add 1 month is different than adding P1M. That's not good - the behavior should be the same. Hence, using milliseconds in the duration plugin is not a feasible option.
test('duration P1M is equivalent one month', () => {
const now = dayjs()
const a = now.add(1, 'month')
const b = now.add(dayjs.duration('P1M'))
const diff = a.diff(b, 'day')
expect(diff).toEqual(0) // <= will fail
})
I just ran into a similar issue to this.
<Text>Today: {dayjs().toString()}</Text>
<Text>Duration: {dayjs.duration("P6W").humanize()}</Text>
<Text>
Today + Duration: {dayjs().add(dayjs.duration("P6W")).toString()}
</Text>