Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make applyDuration reversible #298

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

leduyquang753
Copy link

@leduyquang753 leduyquang753 commented Dec 30, 2024

(This is part of a set of multiple pull requests looking to overhaul the calculation functions.)

When the duration to be applied is negative, this pull request makes the application order of the components reversed compared to when the duration is positive, so that adding a duration to a date then subtracting the same amount yields the same date.

Note: One test is failing on my end from the current upstream code:

relative-time > [tense=future] > micro formats years
AssertionError: expected '3y' to equal '2y'
+ expected - actual

- 3y
+ 2y

This is caused by the current implementation of roundToNearestUnit computing the future date to be in 2027, resulting in a 3-year difference as it only considers the year alone in this case. This will be fixed with a reimplementation of the function in one of my other pull requests.

@leduyquang753 leduyquang753 requested a review from a team as a code owner December 30, 2024 16:29
Comment on lines +111 to +115
if (duration.sign < 0) {
for (const action of durationApplicationActionsBackward) action(r, duration)
} else {
for (const action of durationApplicationActionsForward) action(r, duration)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd prefer to see this without the for loops. I'm a little concerned that they might cause performance regressions (though I have no empirical evidence for that), but more importantly is that I'm not sure they aid readability, and I don't think the unrolled loops would result in a bigger file overall;

export function applyDuration(date: Date | number, duration: Duration): Date {
  const r = new Date(date)
  if (duration.sign < 0) {
    r.setUTCFullYear(r.getUTCFullYear() + duration.years)
    r.setUTCMonth(r.getUTCMonth() + duration.months)
    r.setUTCDate(r.getUTCDate() + duration.weeks * 7 + duration.days)
    r.setUTCHours(r.getUTCHours() + duration.hours)
    r.setUTCMinutes(r.getUTCMinutes() + duration.minutes)
    r.setUTCSeconds(r.getUTCSeconds() + duration.seconds)
  } else {
    r.setUTCSeconds(r.getUTCSeconds() + duration.seconds)
    r.setUTCMinutes(r.getUTCMinutes() + duration.minutes)
    r.setUTCHours(r.getUTCHours() + duration.hours)
    r.setUTCDate(r.getUTCDate() + duration.weeks * 7 + duration.days)
    r.setUTCMonth(r.getUTCMonth() + duration.months)
    r.setUTCFullYear(r.getUTCFullYear() + duration.years)
  }
}

Unless there's a good reason I am missing about using the loop? If that is the case and they need to be kept, I'd quite like to see some benchmarks to see the performance impact of keeping them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's mostly just for DRY, if you say so then I will do it that way.

@keithamus
Copy link
Member

It looks as though there's a test failure - that perhaps should be changed with this change?

@leduyquang753
Copy link
Author

leduyquang753 commented Jan 6, 2025

It looks as though there's a test failure - that perhaps should be changed with this change?

The failing test is not because of or affected by this change as stated in my original comment (it also appears that quite a few tests use new Date() which makes them sensitive to the time of the year).

In the test of the check you run:

 ❌ relative-time > [tense=past] > micro formats years
      AssertionError: expected '11y' to equal '10y'
      + expected - actual
      
      -11y
      +10y
      
      at n4.<anonymous> (test/relative-time.js:531:13)

it is 11y because the test uses new Date() and it is currently the beginning of the year, making the duration rounding code calculate the supposed old date as in 2014 rather than 2015.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants