tc39 / proposal-temporal

Provides standard objects and functions for working with dates and times.
https://tc39.es/proposal-temporal/docs/
Other
3.23k stars 148 forks source link

Editorial: Introduce Record for relativeTo #2837

Open ptomato opened 3 months ago

ptomato commented 3 months ago

After #2826 lands, consider introducing a relativeTo Record in the spec, to show implementations how relativeTo can be handled in a more statically-typed way.

There might be an opportunity to give a formal shape to "relativeTo". Kevin Ness brought this up in the last meeting regarding difficulty in statically typed languages.

type RelativeTo = {
  plainDateTime: Temporal.PlainDateTime
  timeZone: Temporal.TimeZone // or null if UTC?
}

function normalizeRelativeTo(input): RelativeTo {
  if (input instanceof Temporal.ZonedDateTime) {
    return {
      plainDateTime: input.toPlainDateTime(),
      timeZone: input.getTimeZone(),
    }
  } else if (input instanceof Temporal.PlainDate) {
    return {
      plainDateTime: input.toPlainDateTime(), // gives 00:00:00
      timeZone: new Temporal.TimeZone('UTC')
    }
  }
}

/*
Adds a Duration to the relativeTo and returns an epoch nanoseconds
This function is only ever called with time units zeroed out!
(It's just the way our nudging/bubbling system works during relative-rounding)
Thus, we don't need to worry about the intricacies of *when* time units are
added in PlainDateTime vs ZonedDateTime.

A utility function is nice because we don't need to call GetUTCEpochNanoseconds and
GetInstantFor conditionally each time.
*/
function addToRelativeTo(relativeTo: RelativeTo, duration): bigint {
  return relativeTo.timeZone.getInstantFor(
    relativeTo.plainDateTime.add(duration)
  ).epochNanoseconds
}

Originally posted by @arshaw in https://github.com/tc39/proposal-temporal/pull/2758#pullrequestreview-2048722355

ptomato commented 3 months ago

Also use this to eliminate UnbalanceDateDurationRelative as suggested in that review.