user4172337
user4172337

Reputation:

Confusion in java.Clock, systemDefaultZone() returning UTC time

I am trying to understand why the following java.time.Clock is returning UTC time instead of the local time zone (EST).

C:\Users\Felipe>scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_65).
Type in expressions for evaluation. Or try :help.

scala> import java.time._
import java.time._

scala> ZoneId.systemDefault()
res0: java.time.ZoneId = America/New_York

scala> val clock = Clock.systemDefaultZone()
clock: java.time.Clock = SystemClock[America/New_York]

scala> clock.instant
res1: java.time.Instant = 2017-07-06T16:20:04.990Z

The current time when I ran the above was 12:20pm (i.e. 4h before the UTC time shown)

Upvotes: 2

Views: 1853

Answers (2)

user7605325
user7605325

Reputation:

The Instant.toString() method uses DateTimeFormatter.ISO_INSTANT formatter, which in turn parses and formats the Instant in UTC.

As 2017-07-06T16:20:04.990Z is the same as 2017-07-06T12:20:04.990 in New York, the results you're getting are correct.

If you want the Instant converted to your timezone, you can do:

clock.instant().atZone(ZoneId.systemDefault())

Or you can be more specific (as the system's default timezone can be changed, even in runtime):

clock.instant().atZone(ZoneId.of("America/New_York"))

This will result in a ZonedDateTime:

2017-07-06T12:48:22.890-04:00[America/New_York]


You can also convert this to a LocalDateTime if you want:

clock.instant().atZone(ZoneId.of("America/New_York")).toLocalDateTime()

The result will be a LocalDateTime:

2017-07-06T12:49:47.688


PS: as @Andreas reminded me in the comments (and I forgot to mention), the Instant class represents just a point in time (number of nanoseconds since 1970-01-01T00:00Z) and has no timezone information, so any representation of it (including the toString() method) will be in UTC. To get the local date or time that corresponds to an Instant, you must provide a timezone, as shown above.

Upvotes: 3

Manu
Manu

Reputation: 74

Instant does not have any time zone information. It is just the number of seconds/nanoseconds since epoch. LocalDateTime represents time in the local time zone, which can be obtained from clock using:

LocalDateTime.now(clock)

You can also convert an Instant to ZonedDateTime (which represents time along with timezone) using:

clock.instant().atZone(ZoneId.systemDefault())

Upvotes: 1

Related Questions