Hi there, I'm trying to figure why the use of Loca...
# kotlinx-datetime
h
Hi there, I'm trying to figure why the use of LocalDateTime feels discouraged. The docs say "The arithmetic on LocalDateTime values is not provided, since without accounting for the time zone transitions it may give misleading results.". Could you provide an example of such a mistake? I'd love to do
LocalDateTime.now() + 10.hours
, and I struggle to see what's wrong with it.
2
m
I initially wrote an answer but I'm pretty sure it was wrong... Curious about this too 👀
d
If you take for example March 26, 2023, 22:00 as a value for the
LocalDateTime
then it's ambiguous what happens if you add 10 hours to it because that's when daylight saving time starts. If you just add 10 hours to the clock it would be 8:00, but if just waited 10 hours it would be 9:00.
Ofc the example above depends on which time zone you're in (in this case I took the US as an example)
m
Well, that's the thing.
LocalDateTime
isn't timezone aware, is it? So arithmetics could be defined without any time zone, leap second, etc.. considerations
2023-26-03 22:00
+
10.hours
could always equal
2023-27-04 08:00
d
No because "10 hours later" depends on the time zone.
m
What I'm saying is that it could be a choice
We could define the arithmetic to be non time-zone aware
d
Implementing it like that would encourage incorrect date/time calculations.
m
right, I can see how people could expect the wrong thing
And going trhough
Instant
isn't very complicated
But if you're doing arithmetics on something that does'nt contain a time zone, I wouldn't expect the arithmetic to use the time zone?
d
I even wonder what the use case is for the "+10 hours" example mentioned in the original question. My first guess is that it should be implemented in a timezone-aware manner.
You can actually do arithmetic with days, just not time-of-day.
m
I had to do that recently, let me see if I can dig the use case
Alright, it's here
It was to set the end time of a conference talk if none was there
(it was known the talk was 40min)
d
So in this case using UTC time-zone is incorrect. You'd have to use the time zone of where the conference takes place. If the conference was across a DST change boundary this would give the wrong result. I know it's quite an edge-case in your example, but an API should always be correct.
m
Yep, agreed
Alright, I'm convinced! Thanks for the walk through!
d
No worries 😉 Unfortunately working with date/time is always complex and/or annoying. The time zone rules across the world are a hot mess
h
Thanks gentleman for this great thread. Regarding "I even wonder what the use case is for the "+10 hours": I'm working out a production schedule, and was just wondering if the more minimalistic LocalDateTime would be sufficient (since the factory is clearing never moving to a different time zone). However, I understand now that the timezone also models summertime/wintertime transitions, so Instant is the correct choice.
Because I'm old and forgetful, I've created a PR to find this argument maybe later in the documentation itself. See https://github.com/Kotlin/kotlinx-datetime/pull/248
t
fwiw I think this would work with kotlinx.datetime
Copy code
fun getBusinessDay(instant: Instant, timeZone: TimeZone, closeoutTime: LocalTime): LocalDate {
    val localDateTime = instant.toLocalDateTime(timeZone)
    return if (localDateTime.time < closeoutTime) {
        localDateTime.date.minus(1, DateTimeUnit.DAY)
    } else {
        localDateTime.date
    }
}
m
Why do you have to substract? Can't you compare to
2
instead of
0
?
t
Like the example I have above? I guess that’s a fair point. Maybe since it’s not completely necessary to subtract hours in this use case it’s still more beneficial to lock the api down to prevent confusion.
d
If clocks are shifted back due to DST and it takes three actual hours to get from midnight to 02:00, or if the clocks are shifted forward and it takes just an hour to do so, do the businesses adapt the schedule? In other words, what is more important: the mark "02" on the clocks or the actual length of the workday?
t
Just the mark “02”. The actual length of the workday doesn’t matter.
The more I think about this, the more I think the comparison approach is better. A localdatetime is still a representation of a time at a zone, so the subtraction doesn’t really make sense.
d
Also, the subtraction approach is a bit more error-prone:
zonedDateTime.minusHours(closeoutHour).toLocalDate()
would be incorrect, but it looks almost the same.
m
Just bumped into this (
LocalDateTime.plusHours()
). Interesting that Java made the opposite choice.
The Javadoc doesn't give too many details though 😞