Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to convert ZoneId to ZoneOffset in Java 8?

I have an epoch second and a zoneId (see method1 below).

It can be convert to LocalDateTime with system default zoneId, but I don't find the way to convert epoch second to LocalDateTime (see method2 below), because there is no ZoneOffset.systemDefault. I think it's obscure.

import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}  val epochSecond = System.currentTimeMillis() / 1000  // method1 LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault())  // method2 LocalDateTime.ofEpochSecond(epochSecond, 0, ZoneOffset.MAX) 

NOTE

The source code presented above is Scala.

like image 533
Renkai Avatar asked Sep 17 '15 09:09

Renkai


People also ask

What is the difference between a ZoneId and a ZoneOffset?

ZoneId describes a time-zone identifier and provides rules for converting between an Instant and a LocalDateTime . ZoneOffset describes a time-zone offset, which is the amount of time (typically in hours) by which a time zone differs from UTC/Greenwich.

How do I make the system default ZoneOffset?

The systemDefault() method of the ZoneOffset class in Java is used to return the system default time-zone. Parameters: This method does not accepts any parameters. Return Value: This method returns the system default time-zone.

How do I convert ZonedDateTime from one zone to another?

Changing Timezones of ZonedDateTime To convert a ZonedDateTime instance from one timezone to another, follow the two steps: Create ZonedDateTime in 1st timezone. You may already have it in your application. Convert the first ZonedDateTime in second timezone using withZoneSameInstant() method.

What is ZoneId of UTC?

A ZoneId is used to identify the rules used to convert between an Instant and a LocalDateTime . There are two distinct types of ID: Fixed offsets - a fully resolved offset from UTC/Greenwich, that uses the same offset for all local date-times.


2 Answers

Here is how you can get ZoneOffset from ZoneId:

Instant instant = Instant.now(); //can be LocalDateTime ZoneId systemZone = ZoneId.systemDefault(); // my timezone ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant); 

NB: ZoneId can have different offset depending on point in time and the history of the particular place. So choosing different Instants would result in different offsets.

NB2: ZoneId.of() can return a ZoneOffset instead of ZoneId if UTC+3/GMT+2/etc is passed as opposed to a time zone like Africa/Cairo. So if UTC/GMT offsets are passed then historical/geographical/daylight-saving information of the Instant won't be taken into account - you'll simply work with the specified offset.

like image 160
Stanislav Bashkyrtsev Avatar answered Oct 21 '22 12:10

Stanislav Bashkyrtsev


There is no one-to-one mapping. A ZoneId defines a geographic extent in which a set of different ZoneOffsets is used over time. If the timezone uses daylight saving time, its ZoneOffset will be different between summer and winter.

Furthermore, the daylight saving time rules may have changed over time, so the ZoneOffset could be different for e.g. 13/10/2015 compared to 13/10/1980.

So you can only find the ZoneOffset for a ZoneId on a particular Instant.

See also https://en.wikipedia.org/wiki/Tz_database

like image 26
GeertPt Avatar answered Oct 21 '22 10:10

GeertPt