-
Notifications
You must be signed in to change notification settings - Fork 152
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
Options for handling "3 kinds of durations" problem #686
Comments
The current Temporal.Duration was designed as a "bag of options" with the knowledge that a duration is very much context-dependent. The actual amount of time represented by a Temporal.Duration depends on:
Your proposals are various attempts at fixing issue 3. Should we also fix issues 1 and 2 at the same time? The intent with the current design is that the programmer declares all of the context via the type upon which the Temporal.Duration is applied. If you apply it to an Absolute, you get absolute math, and if you have years or months in your Temporal.Duration, you get an exception. If you apply it to a DateTime, you get wall clock math, and you inherit the start date and calendar system from the receiver. Furthermore, I think it's safe to say that the primary purpose of having Absolute and DateTime is so that you can pick how you want to do arithmetic. I think that this problem needs to be seen in context with ZonedAbsolute/LocalDateTime. My current opinion on this matter is:
|
Some observations:
|
These are also my preferences. |
@ryzokuken - do you also want to weigh in on #759 which is a more detailed proposal for Option 3c?
I assume this would mean that What I wasn't sure about: would I'd recommend the latter because (unlike
This is similar to (but 1e6 worse than) the problem that exists today with legacy |
@sffc - rolling up several posts' worth of responses here:
My main concern with the current design is that it's too easy to accidentally move
I've been thinking lately that the best way to handle these use cases is via math methods on the
One benefit of Option 3c, even if we have
I believe that Option 3c fixes all three of these, per bullet 5.5 in #759. Let me know if I missed something about fixing (1) and (2). |
One more note: even if |
This discussion seems to be most relevant to what I wanted to do with It seems that current It looks to me there should be some other |
What's left to discuss on this issue? It seems to me that the round() method and relativeTo solve at least some of the concerns here. |
I believe all the issues with Durations described above have been addressed by the changes in October/November. The idea is that the duration means something different depending on which type you use it with. |
The discussion in #559 and a few other issues highlighted a fundamental challenge with
Duration
: it's impossible to know what a Duration means without knowing how it was constructed.P1DT2H
could have three different meanings:This ambiguity is different from all other Temporal classes. If you have an
Absolute
, you know you're looking at a specific moment in time. If you have aDate
,Time
,DateTime
, etc. you know you're looking at calendar/clock time. The persisted representations are also clear: you can tell from looking at an ISO 8601 date/time string that it's actual or nominal. But aDuration
is always ambiguous. This makes it harder for developers to write DST-safe code.Although docs (e.g. #639) can help, the problem remains that Duration lacks the separation of concerns and unambiguousness of
DateTime
andAbsolute
. So I think it's worth considering what else Temporal can do here.The write-up below outlines possible options to solve this ambiguity.
At a high level, there are three options:
Duration
instance is. This is the current API. We could optionally provide options parameters and/or new methods to make it easier to convert the "wrong" types to the "right" type, like we do withAbsolute<->DateTime
conversions today.kind
field and/or separate classes. Thekind
field should be emitted bygetFields
for object persistence, and optionally we could extend the string persistence format too (e.g. a "Z" suffix for absolute durations).Duration
as one of the three kinds, and ensure thatDuration
-using methods enforce that meaning. For example, ifDuration
means "datetime duration" thenAbsolute.prototype.difference
must require aTimeZone
parameter.Here's variations on each of these options to discuss::
Variations on: Option 1 - "Don't Change Duration data model nor API"
1a. Don't Change Any Temporal APIs on Any Type. Rely on documentation to explain the problem. IMHO this is inconsistent with
DateTime
vs.Absolute
separation of concerns, but it's still a valid choice.Pros:
Cons:
1b. Add Duration Conversion Methods - Provide methods on the
TimeZone
class that convert between the two types of durations, analogous toinTimeZone()
forDateTime
andAbsolute
.Pros:
Cons:
1c. Conversion Methods +
durationKind
Option in Math MethodsTimeZone
(same as 1b)durationKind
option toplus
,minus
, anddifference
to tell Temporal about what kind of duration is in input (forplus
/minus
) or should be in output (fordifference
).timeZone
parameter toplus
,minus
, anddifference
methods. It'd be required ifdurationKind
is the "wrong" kind, and ignored otherwise.Pros:
Cons:
1d.
ZonedAbsolute
+ Defaults - Add a new class type that represents a particular instant at a particular place on earth, and leverage its time zone knowledge for better duration-kind-conversion ergonomics.TimeZone
(same as 1b){durationKind: 'absolute' | 'dateTime' | 'hybrid'}
to this class'splus
/minus
/difference
methods to specify the kind of the input or output duration.'hybrid'
), if we think it will work for a large majority of use cases. Developers could still opt into other kinds by changing the option.Pros:
TimeZone
parameters won't be required in math methods.Cons:
ZonedAbsolute
.Absolute
orDateTime
are out of luck.Variations on: Option 2 - "Change the API and/or Data Model to Differentiate Duration Kinds"
2a. New
XxxDuration
classes - Clone theDuration
type and use class names to clarify if a duration is "absolute", "date/time", or "hybrid".Absolute.prototype.difference
would returnAbsoluteDuration
. This class would only havehours
or smaller units.difference
methods ofDateTime
,Date
,Time
, andYearMonth
would return aDateTimeDuration
.kind: 'absolute' | 'datetime' | 'hybrid'
field (name could betype
,flavor
, etc.) for use in object persistence withgetFields()
andfrom
.from
andwith
would throw if the wrongkind
field is provided for that class.AbsoluteDuration
would have time fields but no date fields, to more clearly communicate to users that "absolute days" don't really exist.TimeZone
(same as 1b)TimeZone
parameter onplus
/minus
methods, which would be required for durations of thewrong
types but optional for durations of theright
type. This would be a convenience to avoid developers having to call the kind-conversion methods on TimeZone before or after many calls toplus
/minus
/difference
.ZonedAbsolute
type would not need this parameter because it already knows the time zone.plus
orminus
methods (orDuration.prototype.from
orDuration.prototype.with
) would be assumed to have the "right" type, unless they contain akind
of the wrong type. This supports common cases like.plus({days: 1})
without having to specify a kind, under the assumption that if developers build property bags themselves, then they know what they're doing.XxxDuration
classes'plus
/minus
/difference
methods would throw if provided an instance of another kind.Pros:
DateTime
/Absolute
split in Temporal, so will be relatively easy to explain and learnCons:
timeZone
parameters are sometimes required and sometimes optional-- is that weird?2b. New
XxxDuration
classes + ISO String Extensions - Same as 2a, but also extend persistence formats with duration kind info.Absolute
string persistence)DateTime
string persistence), or it could get a different suffix character like "C" (for "calendar/clock"), e.g. "P2DT12HC".P2DZT12HZ
would represent a 36-hour absolute duration whileP2DT12HZ
would mean "2 calendar days and 12 absolute hours". A cleaner approach might be to use another suffix character, e.g.P2DT12HQ
.from
methods would throw if provided a string of the wrong kind for that duration class.Pros:
kind
.Cons:
2c. Single Duration Class Type with
kind
FieldLike Option 2a, but rely on the
kind
field instead of class name to differentiate duration kinds.from
(using an object initializer) must require akind
parameter.Pros:
Duration.from()
without knowing in advance what kind of duration is input.Cons:
Absolute
vs.DateTime
split we already have.2d. Single Duration Class Type with
kind
Field + ISO PersistenceSame as Option 2b, but rely on the
kind
field instead of the class type to differentiate different flavors of durations.Pros:
Duration.from()
without knowing in advance what kind of duration is inputCons:
Variations on: Option 3 - "Pick and enforce one of the three meanings for Duration"
3a. Specify that Duration Means "Absolute Duration" -
Absolute
'splus
,minus
, anddifference
methods would continue to accept & returnDuration
, while other types'plus
,minus
, anddifference
methods would add a requiredtimeZone
parameter. (ExceptZonedAbsolute
wouldn't require atimeZone
parameter because it knows its time zone.)Pros:
ZonedAbsolute
Cons:
ZonedAbsolute
types : adds requiredtimeZone
parameter to almost every Temporal method that accepts or returns a duration.3b. Specify that Duration is Only "DateTime Duration" - This is the inverse of Option 3a.
Absolute
'splus
/minus
/difference
methods would get a requiredtimeZone
parameter, while all other types would stay as-is.Pros:
Absolute
DateTime
/Date
/Time
/etc side of TemporalZonedAbsolute
Cons:
3c. Specify that Temporal
Duration
matches RFC 5545: date fields represent aDateTime
difference, while time fields represent anAbsolute
difference - This combines Option 3a and 3b and matches how RFC 5545 defines a duration: a combination of a date/time date-only duration and an absolute time-only duration. SoPT2H
would be considered absolute time,P2D
would be two calendar days, andP2DT2H
would mean 2 calendar days plus 2 real-world hours.Pros
ZonedAbsolute
hours
as the largest unit.Cons
TimeZone
and a starting date would be required for Duration'splus
/minus
/difference
TimeZone
would be required for all non-Duration types'plus
/minus
/difference
methods (exceptZonedAbsolute
)The text was updated successfully, but these errors were encountered: