Reputation: 1403
I have the time in seconds from our computers "Day 0" (a.k.a. midnight, January 1st 1970 UTC) and I want to convert that into a LocalDateTime instance. This code will do that:
LocalDateTime dateTime = LocalDateTime.ofEpochSecond(seconds, 0, ZoneOffset.UTC)
Nevertheless, I need this LocalDateTime to be in my timezone. Changing ZoneOffset.UTC
to ZineOffset.of("+2)
will bring the LocalDateTime to display the correct time. (For, let's say Paris as of 8/31/2015)
But this is more or less an imperfect workaround, as it does not take care of Daylight Saving Time.
So I tried around a bit more, and found the ZonedDateTime
class. It didn't help me out either, but I got stuck here:
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(seconds, 0, ZoneOffset.UTC);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime,ZoneId.systemDefault());
This doesn't work at all though, as ZonedDateTime
contains a LocalDateTime
which then contains a LocalTime
which is my time in UTC, rather then in my current time zone.
So how do you get a LocalDateTime
in the (preferably) Systems time Zone including Daylight Saving Time (if needed) from a UTC seconds-from-epoche value?
Upvotes: 7
Views: 13243
Reputation: 16938
You need to specify the ZoneId
in order to have the daylight savings from a geographical region taken into account. Get a list of available zone IDs:
System.out.println(ZoneId.getAvailableZoneIds());
With the correct zone ID, you'll have access to the daylight saving rules.
For example, in Germany (UTC+1) they had the first daylight savings in 1940 (UTC+2). In 1947, they introduced the midsummer time, being two hours ahead of the standard winter time (=UTC+3). Here's an example for summer 1940, 1947, 1970 (no daylight savings) and this morning:
Instant[] instants = new Instant[] {
LocalDateTime.of(1939, 6, 1, 0, 0).toInstant(ZoneOffset.UTC),
LocalDateTime.of(1940, 6, 1, 0, 0).toInstant(ZoneOffset.UTC),
LocalDateTime.of(1947, 6, 1, 0, 0).toInstant(ZoneOffset.UTC),
Instant.ofEpochSecond(0), // 1970-01-01T00:00:00 UTC
LocalDateTime.of(1970, 6, 1, 0, 0).toInstant(ZoneOffset.UTC),
Instant.now().truncatedTo(ChronoUnit.DAYS), // 2015-08-31T00:00:00 UTC
};
for (Instant instant : instants) {
LocalDateTime inBerlin = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Berlin"));
System.out.println("UTC " + instant.atOffset(ZoneOffset.UTC).toLocalDateTime());
System.out.println("BERLIN " + inBerlin);
System.out.println();
}
This will print something like:
UTC 1939-06-01T00:00
BERLIN 1939-06-01T01:00
UTC 1940-06-01T00:00
BERLIN 1940-06-01T02:00
UTC 1947-06-01T00:00
BERLIN 1947-06-01T03:00
UTC 1970-01-01T00:00
BERLIN 1970-01-01T01:00
UTC 1970-06-01T00:00
BERLIN 1970-06-01T01:00
UTC 2015-08-31T00:00
BERLIN 2015-08-31T02:00
As you can see, the rules are implemented correctly. The first daylight savings in Berlin were 1940. In 1947, there were daylight savings with an additional hour shift. In the years from 1950 - 1980 there were no daylight savings at all. In 1980, many countries in Europe had an orchestrated start of daylight savings.
Oh, to answer your question:
LocalDateTime.ofInstant(Instant.ofEpochSecond(seconds), ZoneId.systemDefault())
Upvotes: 14