Datest, offsets and timezones in java

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.

Jon Skeet
people
quotationmark

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.

people

See more on this question at Stackoverflow