iamkun / iamkun/dayjs

dayjs.duration() improvement

Open
#2,572 0 comments 2 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
48.7k
Forks
2.5k
PR merge metrics
No merged PRs in 30d

Description

Current implementation of ```dayjs.duration``` causes confusion for people. I suppose because it is not clear enough from the docs that the calculated duration uses average values for the year and month durations, in addition to the wrong average value calculations - https://github.com/iamkun/dayjs/issues/2571

It would make sense to me if the method could calculate average duration based on the milliseconds provided as argument, or intuitive "precise" duration, if two dates are provided as arguments.

Here is what I mean:
```
function getParsedDate(date: Date) {
return {
milliseconds: date.getMilliseconds(),
seconds: date.getSeconds(),
minutes: date.getMinutes(),
hours: date.getHours(),
day: date.getDate(),
month: date.getMonth(),
year: date.getFullYear(),
};
}

function duration(dateA: Date, dateB: Date) {
const [start, end] = [new Date(dateA), new Date(dateB)].sort(
(a, b) => a.getTime() - b.getTime(),
);
const from = getParsedDate(start);
const to = getParsedDate(end);
const result = {
milliseconds: 0,
seconds: 0,
minutes: 0,
hours: 0,
days: 0,
months: 0,
years: 0,
};

result.milliseconds = to.milliseconds - from.milliseconds;
if (result.milliseconds < 0) {
result.seconds = -1;
result.milliseconds += 1000;
}

result.seconds = result.seconds + to.seconds - from.seconds;
if (result.seconds < 0) {
result.minutes = -1;
result.seconds += 60;
}

result.minutes = result.minutes + to.minutes - from.minutes;
if (result.minutes < 0) {
result.hours = -1;
result.minutes += 60;
}

result.hours = result.hours + to.hours - from.hours;
if (result.hours < 0) {
result.days = -1;
result.hours += 24;
}

result.days = result.days + to.day - from.day;
if (result.days < 0) {
result.months = -1;
result.days += new Date(to.year, to.month, 0).getDate();
}

result.months = result.months + to.month - from.month;
if (result.months < 0) {
result.years = -1;
result.months += 12;
}

result.years = result.years + to.year - from.year;

return result;
}

console.log(
duration(
new Date('2024-02-16T15:26:55.505'),
new Date('2025-02-16T15:26:55.506'),
),
);
```

This is not a bug report, but an improvement request/proposal. What are your thoughts about it?

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the current dayjs.duration implementation and the documentation describing its year and month calculations. Compare the proposed millisecond-based and two-date behavior with the existing API, then establish the expected results and corresponding tests before making a change.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
api
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.