You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While reviewing #2003 and looking at implementation concerns raised in #1863, I looked more closely at the PlainYearMonth add/subtract algorithm in the spec and noticed interesting behavior: when adding (or subtracting a negative duration), we treat the receiver as if it were the first nanosecond of the month, but when subtracting we treat it as the last nanosecond of the month. The same behavior seems to be present in PlainDate add/subtract, where subtracting one hour from a PlainDate yields the same value because we treat the receiver as if was the last nanosecond of the day.
Is this behavior what callers will expect? Specifically:
AFAICT, in all other Temporal contexts we treat a PlainDate as if it were the first nanosecond of the day, and treat a PlainYearMonth as the first nanosecond of the month. Why is this case different? For example, in Calendar-ignoring compare behaves unexpectedly for non-ISO calendar PlainYearMonth comparisons #1846 we decided that when comparing PlainYearMonth instances across calendars, we'd treat a PlainYearMonth as the first day of the calendar month.
When combining addition with converting PlainDate to PlainDateTime (or PlainYearMonth to PlainDate or PlainDateTime), will it be expected that order-of-operations should cause different results? EDIT: I updated this example to be clearer
/** add a duration to a date, and then return a PlainDateTime for noon on the resulting day */functionnoonOnAddedDate1(plainDate,duration){constpdt=plainDate.toPlainDateTime();constadded=pdt.add(duration);constresult=added.withPlainTime('12:00');returnresult;}/** same as above, but will return different result for negative durations with nonzero time units */functionnoonOnAddedDate2(plainDate,duration){constadded=plainDate.add(duration);constresult=added.toPlainDateTime('12:00');returnresult;}date=Temporal.PlainDate.from('2020-01-01');duration=Temporal.Duration.from('-PT12H');noonOnAddedDate1(date,duration);// => 2019-12-31T12:00:00noonOnAddedDate2(date,duration);// => 2020-01-01T12:00:00
Anyway, seems like we have three options:
Leave current behavior as-is, and document it
Change add/subtract to be consistent with other part of temporal by treating PlainDate as the first nanosecond of the day and PlainYearMonth as the first nanosecond of the month.
Throw if the user calls PlainDate add/subtract with non-zero hours (or smaller units) or calls PlainYearMonth with non-zero days (or smaller units).
My opinion is that (2) or (3) will be easier for callers to predict and understand. I'm not sure any developer will expect (1) unless they read the spec or (when we update them) the docs.
The text was updated successfully, but these errors were encountered:
The reason I think (1) is not so weird, is because of the semantics we came up with in that thread: when adding duration units smaller than the receiver's smallest unit, balance them up to the smallest valid unit for that type, and discard any remainder. That's equivalent to the semantics that the spec describes for PlainYearMonth (balance up to days and treat the date as the last day of the month when subtracting), only it saves some observable calendar method calls, but sounds a lot more intuitive.
A counter to (2) would be that I'd find this pretty unexpected:
constdate=Temporal.Now.plainDateISO();date.add({hours: 12})// same datedate.subtract({hours: 12})// different date?!
I think I probably left this out of the documentation for brevity, but I personally wouldn't mind if it were added now. I'd make different choices nowadays than I did 2 years ago on what to include since we're in a different stage of the proposal now.
Aside from the above...
When combining addition with converting PlainDate to PlainDateTime (or PlainYearMonth to PlainDate or PlainDateTime), will it be expected that order-of-operations should cause different results?
I think I disagree with you that this is unexpected. I wouldn't expect these to be order-independent. I thought your original example (now edited out) was actually more illustrative of this. IIRC it was
date.add({hours: 1}).toPlainDateTime() vs.
date.toPlainDateTime().add({hours: 1})
If these had to produce the same result, that would mean that PlainDate would have to have hidden state where it kept track of the 1 hour that had been added before it was converted to PlainDateTime.
Given that this is a decision that we already made in #324, and no new information has come to light, I'm strongly in favour of (1): leave the current behaviour as is, and document it.
While reviewing #2003 and looking at implementation concerns raised in #1863, I looked more closely at the PlainYearMonth add/subtract algorithm in the spec and noticed interesting behavior: when adding (or subtracting a negative duration), we treat the receiver as if it were the first nanosecond of the month, but when subtracting we treat it as the last nanosecond of the month. The same behavior seems to be present in PlainDate add/subtract, where subtracting one hour from a PlainDate yields the same value because we treat the receiver as if was the last nanosecond of the day.
Is this behavior what callers will expect? Specifically:
compare
behaves unexpectedly for non-ISO calendar PlainYearMonth comparisons #1846 we decided that when comparing PlainYearMonth instances across calendars, we'd treat a PlainYearMonth as the first day of the calendar month.Anyway, seems like we have three options:
My opinion is that (2) or (3) will be easier for callers to predict and understand. I'm not sure any developer will expect (1) unless they read the spec or (when we update them) the docs.
The text was updated successfully, but these errors were encountered: