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

ZonedDateTime hoursInDay, startOfDay, round, add, subtract #1103

Merged
merged 7 commits into from
Nov 3, 2020

Conversation

ptomato
Copy link
Collaborator

@ptomato ptomato commented Nov 3, 2020

See: #569

Co-authored-by: Justin Grant <justingrant@users.noreply.github.com>

See: #569
Co-authored-by: Justin Grant <justingrant@users.noreply.github.com>

See: #569
Note this implementation is incorrect for rounding to the nearest day on
days where a DST transition takes place. This case will be handled
correctly when we implement ZonedDateTime difference algorithms for
since() and until(). There are two tests dealing with these cases which
are skipped for the time being.

Co-authored-by: Justin Grant <justingrant@users.noreply.github.com>

See: #569
This operation will be reused in ZonedDateTime.add() and subtract() as
well.

See: #569
Two tests are skipped due to the change in order-of-operations that will
land in #993.

Co-authored-by: Justin Grant <justingrant@users.noreply.github.com>

See: #569
The message is no longer accurate, since ZonedDateTime itself has landed
already. Change it to say which methods are as yet unimplemented.
@codecov
Copy link

codecov bot commented Nov 3, 2020

Codecov Report

Merging #1103 into main will decrease coverage by 3.38%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1103      +/-   ##
==========================================
- Coverage   93.55%   90.16%   -3.39%     
==========================================
  Files          19       17       -2     
  Lines        7961     8178     +217     
  Branches     1264     1182      -82     
==========================================
- Hits         7448     7374      -74     
- Misses        506      794     +288     
- Partials        7       10       +3     
Flag Coverage Δ
test262 ?
tests 90.16% <ø> (+0.73%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
polyfill/lib/legacydate.mjs
polyfill/lib/regex.mjs
polyfill/lib/time.mjs
polyfill/lib/yearmonth.mjs
polyfill/lib/now.mjs
polyfill/lib/date.mjs
polyfill/lib/duration.mjs
polyfill/lib/datetime.mjs
polyfill/lib/temporal.mjs
polyfill/lib/intl.mjs
... and 23 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e8dbc65...e6594b3. Read the comment docs.

Copy link
Collaborator

@justingrant justingrant left a comment

Choose a reason for hiding this comment

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

Looks great. It's so cool to see ZDT coming alive! I made a few minor suggestions and notes. Nothing major.

polyfill/lib/zoneddatetime.mjs Show resolved Hide resolved
const timeZone = GetSlot(this, TIME_ZONE);
const todayNs = GetSlot(ES.GetTemporalInstantFor(timeZone, today, 'compatible'), EPOCHNANOSECONDS);
const tomorrowNs = GetSlot(ES.GetTemporalInstantFor(timeZone, tomorrow, 'compatible'), EPOCHNANOSECONDS);
let { seconds, milliseconds, microseconds, nanoseconds } = ES.DifferenceInstant(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is all the code below here needed? Could it be replaced with something like this?

return Number(tomorrowNs - todayNs) / 3.6e12;

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or is there some non-ISO time calendar reason to want to do it the way you did?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point. We still do need to calculate the quotient and remainder separately because BigInt division is integer division, but this can be simplified a lot.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not just convert the difference to a Number and then use floating-point Number math? If a "day" is longer than 140 24-hour days, some precision loss seems OK. ;-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In the spec text, the epoch nanoseconds are mathematical values (ℝ values) so you have to be explicit about when you convert them to Number values, my guess is that this is the cleanest way.

polyfill/test/zoneddatetime.mjs Show resolved Hide resolved
const timeZone = GetSlot(this, TIME_ZONE);
const offsetNs = ES.GetOffsetNanosecondsFor(timeZone, GetSlot(this, INSTANT));

// See the 'prefer' algorithm in ToTemporalZonedDateTime
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't fully follow this logic here, but as long as tests pass I assume it's fine.

polyfill/test/zoneddatetime.mjs Show resolved Hide resolved

// RFC 5545 requires the date portion to be added in calendar days and the
// time portion to be added in exact time.
// FIXME: "op" and the dateAdd/dateSubtract conditional will not be needed
Copy link
Collaborator

Choose a reason for hiding this comment

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

This comment doesn't match the code below. What conditional?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry, left over from a previous version where I was trying to keep both AddZonedDateTime and SubtractZonedDateTime consolidated into one function. I'll remove this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Cool. Please leave the note about #993 though! Will be helpful for me to find places to fix along with #993. I'm assuming that these AOs should be consolidated the #993 fix-- LMK if not.

Copy link
Collaborator

Choose a reason for hiding this comment

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

BTW, I'm hoping to finish the #993 fix today. Tomorrow at latest.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There is still a note about #993 in SubtractZonedDateTime, so that should be fine.

polyfill/test/zoneddatetime.mjs Show resolved Hide resolved
Copy link
Collaborator

@Ms2ger Ms2ger left a comment

Choose a reason for hiding this comment

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

Thanks for the careful review, @justingrant. It seems like none of your/my comments particularly justify holding this up, so I'll merge now, and let @ptomato deal with them in the next PR.

1. Let _isoCalendar_ be ? GetISO8601Calendar().
1. Let _today_ be ? CreateTemporalDateTime(_year_, _month_, _day_, 0, 0, 0, 0, 0, 0, _isoCalendar_).
1. Let _tomorrowFields_ be ? AddDate(_year_, _month_, _day_, 0, 0, 0, 1, *"reject"*).
1. Let _tomorrow_ be ? CreateTemporalDateTime(_tomorrowFields_.[[ISOYear]], _tomorrowFields_.[[ISOMonth]], _tomorrowFields_.[[ISODay]], 0, 0, 0, 0, 0, 0, _isoCalendar_).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Check if tomorrowFields's fields start with ISO

1. Let _rounded_ be ? CreateTemporalDateTime(_roundResult_.[[Year]], _roundResult_.[[Month]], _roundResult_.[[Day]], _roundResult_.[[Hour]], _roundResult_.[[Minute]], _roundResult_.[[Second]], _roundResult_.[[Millisecond]], _roundResult_.[[Microsecond]], _roundResult_.[[Nanosecond]], _calendar_).
1. Let _offsetNanoseconds_ be ? GetOffsetNanosecondsFor(_timeZone_, _instant_).
1. Let _possibleInstants_ be ? GetPossibleInstantsFor(_timeZone_, _rounded_).
1. If there exists an element _candidate_ of _possibleInstants_ for which ? GetOffsetNanosecondsFor(_timeZone_, _candidate_) = _offsetNanoseconds_, then
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should make the order of operations explicit, since all the GetOffsetNanosecondsFor calls are observable

@Ms2ger Ms2ger merged commit a368ad3 into main Nov 3, 2020
@Ms2ger Ms2ger deleted the zoneddatetime-3 branch November 3, 2020 10:06
@ptomato
Copy link
Collaborator Author

ptomato commented Nov 3, 2020

Thanks for the reviews, I've got fixes for all of these on my next branch.

This pull request was closed.
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.

3 participants