-
Notifications
You must be signed in to change notification settings - Fork 111
Ensure better ISO 8601 compliance #330
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
Conversation
ISO 8601 defines the period of one month as a fixed number of calendar days, specified by the calendar. Before this change, we treated a month as a separate time scale unit during `DatePeriod` arithmetics, namely, we resolved the `LocalDateTime` on which we did arithmetics internally after adding the months but before adding the days. This change makes it so that adding months and days is done as a single change, only consulting the calendar, and the time zone is only used once all calendar-based operations are performed. The code that calculates the `DateTimePeriod` between two `Instant` values is changed symmetrically.
throw DateTimeArithmeticException("The number of months between $this and $other does not fit in an Int") | ||
} | ||
thisDate = thisDate.plus(days, DateTimeUnit.DAY) // won't throw: thisLdt + days <= otherLdt | ||
val thisInstant = LocalDateTime(thisDate, thisLdt.time).toInstant(timeZone) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this toInstant
use the same resolve mode as ZDT.plus(days)
that was used before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not exactly.
Imagine a situation:
- UTC offset before is
+1:00
; - An overlap happens;
- UTC offset after is
+0:00
.
If we subtract, say, a day and land into this overlap, then, as is currently implemented, the +0:00
offset will be used. In this PR, the UTC offset +1:00
will be used instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it would be better to preserve resolve behavior in these operations, so that
Instant + DatePeriod(days = 1) == Instant.plus(1, DAY)
@@ -11,6 +11,7 @@ import kotlinx.datetime.internal.* | |||
import kotlinx.datetime.serializers.InstantIso8601Serializer | |||
import kotlinx.serialization.Serializable | |||
import java.time.DateTimeException | |||
import java.time.ZonedDateTime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accidental import?
ISO 8601 defines the period of one month as a fixed number of calendar days, specified by the calendar.
Before this change, we treated a month as a separate time scale unit during
DatePeriod
arithmetics, namely, we resolved theLocalDateTime
on which we did arithmetics internally after adding the months but before adding the days.This change makes it so that adding months and days is done as a single change, only consulting the calendar, and the time zone is only used once all calendar-based operations are performed.
The code that calculates the
DateTimePeriod
between twoInstant
values is changed symmetrically.