Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Java 8's new Java Date Time API take care of DST?

I am thinking of using the new java 8 Date Time API. I googled a bit and found jodaTime as good choice for java but still kind of interested to see how this new API works.

I am storing all time in UTC values in my datastore and will be converting them to Local Time Zone specific value based on user's timezone. I can find many articles showing how to use new Java Date Time API. However I am not sure if the API will take care of DST changes ? Or do we have any better way of handling Date ?

I am just learning the new Date API , so thought of hearing your thoughts on handling the DateTime and displaying it on the basis of Users TimeZone.

like image 824
Raja Avatar asked Sep 29 '15 00:09

Raja


People also ask

What is the feature of the new date and time API in Java 8?

The new date-time API is immutable and does not have setter methods. Poor design − Default Date starts from 1900, month starts from 1, and day starts from 0, so no uniformity. The old API had less direct methods for date operations. The new API provides numerous utility methods for such operations.

How does Java handle daylight savings code?

The right way to handle DST in Java is to instantiate a Timezone with a specific TZDB Timezone ID, eg. “Europe/Rome”. Then, we'll use this in conjunction with time-specific classes like java.

Can you provide some APIs of Java 8 date and time?

Java 8 provides APIs for the easy formatting of Date and Time: LocalDateTime localDateTime = LocalDateTime. of(2015, Month. JANUARY, 25, 6, 30);

Does ZonedDateTime handle Daylight Savings?

Instant represents a point in time in the UTC time zone. OffsetDateTime represents a point in time with an offset (any offset). ZonedDateTime represents a point in time in a time zone (any time zone), adding full time zone rules like daylight saving time adjustments.


2 Answers

It depends on which class you use:

  • Instant is an instantaneous point on the global time-line (UTC), and is unrelated to time-zone.
  • LocalDate and LocalDateTime have no concept of time-zone, but calling now() will of course give you your correct time.
  • OffsetDateTime has a time-zone, but doesn't support Daylight Savings Time.
  • ZonedDateTime has full time-zone support.

Converting between them usually requires a time-zone, so to answer your question:

    Yes, Java 8 Date/Time can take care of DST, if you use it right.

like image 82
Andreas Avatar answered Sep 23 '22 18:09

Andreas


The Answer by Andreas is spot-on correct.

Example Code

Let's test it with some code. DST in the United States & Canada expires this year at 02:00 on November 1, 2015.

Let‘s start with 1 AM in “local” date-time, meaning not tied to the timeline and ignoring the issue of time zones. Add an hour, and we get 2 AM. Makes sense.

LocalDateTime localDateTime = LocalDateTime.of( 2015 , Month.NOVEMBER , 1 , 1 , 0 ); // 1 AM anywhere. Not tied the timeline nor to any time zone. LocalDateTime localDateTimeOneHourLater = localDateTime.plusHours( 1 ); // 2 AM anywhere, in no particular time zone, ignoring DST. 

Next we get specific, with a particular time zone. We take that 1 AM anywhere and put it into the time zone of America/Los_Angeles (west coast of United States).

ZoneId zoneId_LosAngeles = ZoneId.of( "America/Los_Angeles" ); ZonedDateTime before = localDateTime.atZone( zoneId_LosAngeles ); // Assign a time zone, tying this vague date-time idea/generality to an actual moment on the time line. 

Now add an hour, and see what we get. If DST is ignored, we’ll get 2 AM. If DST is respected, we’ll get 1 AM… when reaching 2 AM the wall-clock time jumps back to 1 AM but with a new offset-from-UTC. This is colloquially known as "fall back" in the fall (autumn).

ZonedDateTime after = before.plusHours( 1 ); // 2 AM? Nope, 1 AM because DST Daylight Saving Time expires at 2 AM Nov 1, 2015. 

Dump to console.

System.out.println( "localDateTime : " + localDateTime ); System.out.println( "localDateTimeOneHourLater : " + localDateTimeOneHourLater ); System.out.println( "before : " + before ); System.out.println( "after : " + after ); 

When run, we get this output. Without a time zone, 1 AM + 1 hour = 2 AM. Remember these are "local" date-time values, not UTC. They represent only the vague idea of a date-time, not an actual moment on the timeline.

localDateTime : 2015-11-01T01:00 localDateTimeOneHourLater : 2015-11-01T02:00 

But with time zones applied on the day DST expires, we get different results. Note how the time-of-day remains 01:00 but the offset-from-UTC changes from -07:00 to -08:00.

before : 2015-11-01T01:00-07:00[America/Los_Angeles] after : 2015-11-01T01:00-08:00[America/Los_Angeles] 

Perhaps this would more clear and easier to verify if we adjust into UTC. We can do that simply by accessing the before and after objects as Instant objects. The System.out.println then implicitly calls the toString method.

System.out.println( "before.toInstant : " + before.toInstant() ); System.out.println( "after.toInstant : " + after.toInstant() ); 

When run.

before.toInstant : 2015-11-01T08:00:00Z after.toInstant : 2015-11-01T09:00:00Z 

Table of date-time types in Java, both modern and legacy


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

like image 24
Basil Bourque Avatar answered Sep 19 '22 18:09

Basil Bourque