I'm trying to understand the underlying mechanic of temporal utilities.
So, I made the next example:
public class Test {
public static void main(String[] args) {
System.out.println(Instant.now().getEpochSecond());
System.out.println(new Date().getTime());
System.out.println(LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond());
System.out.println(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
System.out.println(ZoneId.systemDefault().toString());
}
}
Output is:
1460651620
1460651620182
1460651620
1460662420
Europe/Helsinki
My current systemDefault zoneId is Europe/Helsinki (+3 hours)
When we create new Date()
it has the unix timestamp (UTC).
This is my base point to compare printed results.
1. In my third System.out
I have the LocalDateTime with established timezone systemDefault
but output is actually the same. I expected the bigger value (+3 hours).
2. In fourth output line I although have confusing result. I expected the same value with new Date().getTime()
Need some help to understand the output.
I have the LocalDateTime with established timezone systemDefault
No, you don't. You started with a LocalDateTime
, but then you converted it into a ZonedDateTime
. A ZonedDateTime
is effectively a LocalDateTime
with a ZoneId
and an offset from UTC to handle ambiguity.
LocalDateTime
doesn't have a toEpochSecond()
method, because it doesn't represent a fixed point in time. It has toEpochSecond(ZoneOffset)
because that "anchors" the local date/time to a fixed point in time by applying a UTC offset.
Compare that with ZonedDateTime
which does have a parameterless toEpochSecond()
method, because it represents a fixed point in time, with the additional context of a time zone. (You can either view a ZonedDateTime
as an Instant
with a ZoneId
, or a LocalDateTime
with a ZoneId
and a ZoneOffset
; they're equivalent, but personally I prefer the latter notion.)
Note that your code could give you a different result - if you were in a period where LocalDateTime.now()
was ambiguous due to the clocks going back (typically at the end of daylight saving). In that case, LocalDateTime.atZone
picks the earlier occurrence of that LocalDateTime
, whereas in reality you might be experiencing the later occurrence. That's the difference between LocalDateTime.now().atZone(zone)
and ZonedDateTime.now(zone)
- the latter will always "know" the offset correctly.
See more on this question at Stackoverflow