Java API for Daylight Saving Time Throughout the Year

I have a date range (start and end date) and you need to know if this applies to daylight saving time changeover.

Is there any Java API to test this or any Java code to achieve this?

+3


source to share


2 answers


Daytime changes occur on different dates in each country / region, so the first thing to know is the name of the timezone you are checking.

I am writing this answer using both Joda-Time and the new Java Date / Time API and both use a list of IANA timezone names (in format Continent/City

). Both APIs also avoid using 3-letter names because they are ambiguous and not standard .

In the code below, I will use America/Sao_Paulo

(the timezone I live in, which changes DST every year), but you can replace it with your required timezone.

The code below shows how to check if a date is in DST and find the next date when DST changes. So, if you have start and end dates and want to know if they are within the DST change, you can check if they are in DST or not, and also find the next and previous DST changes (and check if the dates match those changes - it's not clear to me how your check should be done).


Also remember that Joda-Time is in maintenance mode and is being replaced by new APIs, so I don't recommend starting a new project with it. Even the joda website says, "Please note that Joda-Time is considered pretty much a 'off the shelf' project. If you are using Java SE 8, go to java.time (JSR-310) ..


Joda time

You can use the class org.joda.time.DateTimeZone

. For all available time zones, call DateTimeZone.getAvailableIDs()

.

The code below checks if a date is in DST and also finds the next date when DST changes:

// create timezone object
DateTimeZone zone = DateTimeZone.forID("America/Sao_Paulo");

// check if a date is in DST
DateTime inDst = new DateTime(2017, 1, 1, 10, 0, zone);
// isStandardOffset returns false (it in DST)
System.out.println(zone.isStandardOffset(inDst.getMillis()));
// check when it'll be the next DST change
DateTime nextDstChange = new DateTime(zone.nextTransition(inDst.getMillis()), zone);
System.out.println(nextDstChange); // 2017-02-18T23:00:00.000-03:00

// check if a date is in DST
DateTime noDst = new DateTime(2017, 6, 18, 10, 0, zone);
// isStandardOffset returns true (it not in DST)
System.out.println(zone.isStandardOffset(noDst.getMillis()));
// check when it'll be the next DST change
nextDstChange = new DateTime(zone.nextTransition(noDst.getMillis()), zone);
System.out.println(nextDstChange); // 2017-10-15T01:00:00.000-02:00

      



If you want to find a previous DST change (instead of the next one), call previousTransition()

instead nextTransition()

.


New Java Date / Time API

If you are using Java 8 , the new java.time API comes natively already.

If you're using Java <= 7 , you can use the ThreeTen Backport , a great backport for Java 8's new date and time classes. And for Android there is ThreeTenABP (more on how to use it here ).

Below is the code below. The only difference is the package names (in Java 8 - java.time

, and in ThreeTen Backport (or Android ThreeTenABP) - org.threeten.bp

), but the class and method names are the same.

The code is very similar to the Joda-Time version. The main differences are:

  • While Joda-Time has isStandardOffset()

    to check if a date is not in DST, the new API has isDaylightSavings()

    to check if a date is in DST.
  • Joda-Time provides methods directly in the class DateTimeZone

    , but the new API has a dedicated class for its DST ( java.time.zone.ZoneRules

    ) rules
  • The Next and Previous Jump methods return a java.time.zone.ZoneOffsetTransition

    instead of directly returning the date (this object provides more information on DST modification, as shown below).

Despite all these differences, the idea is very similar:

// create timezone object
ZoneId zone = ZoneId.of("America/Sao_Paulo");
// get the timezone rules
ZoneRules rules = zone.getRules();

// check if a date is in DST
ZonedDateTime inDST = ZonedDateTime.of(2017, 1, 1, 10, 0, 0, 0, zone);
// isDaylightSavings returns true (it in DST)
System.out.println(rules.isDaylightSavings(inDST.toInstant()));
// check when it'll be the next DST change
ZoneOffsetTransition nextTransition = rules.nextTransition(inDST.toInstant());
// getInstant() returns the UTC instant; atZone converts to the specified timezone
System.out.println(nextTransition.getInstant().atZone(zone)); // 2017-02-18T23:00-03:00[America/Sao_Paulo]

// you can also check the date/time and offset before and after the DST change
// in this case, at 19/02/2017, the clock is moved 1 hour back (from midnight to 11 PM)
ZonedDateTime beforeDST = ZonedDateTime.of(nextTransition.getDateTimeBefore(), nextTransition.getOffsetBefore());
System.out.println(beforeDST); // 2017-02-19T00:00-02:00
ZonedDateTime afterDST = ZonedDateTime.of(nextTransition.getDateTimeAfter(), nextTransition.getOffsetAfter());
System.out.println(afterDST); // 2017-02-18T23:00-03:00

// check if a date is in DST
ZonedDateTime noDST = ZonedDateTime.of(2017, 6, 1, 10, 0, 0, 0, zone);
// isDaylightSavings returns false (it not in DST)
System.out.println(rules.isDaylightSavings(noDST.toInstant()));
// check when it'll be the next DST change
nextTransition = rules.nextTransition(noDST.toInstant());
// getInstant() returns the UTC instant; atZone converts to the specified timezone
System.out.println(nextTransition.getInstant().atZone(zone)); // 2017-10-15T01:00-02:00[America/Sao_Paulo]

// you can also check the date/time and offset before and after the DST change
// in this case, at 15/10/2017, the clock is moved 1 hour forward (from midnight to 1 AM)
beforeDST = ZonedDateTime.of(nextTransition.getDateTimeBefore(), nextTransition.getOffsetBefore());
System.out.println(beforeDST); // 2017-10-15T00:00-03:00
afterDST = ZonedDateTime.of(nextTransition.getDateTimeAfter(), nextTransition.getOffsetAfter());
System.out.println(afterDST); // 2017-10-15T01:00-02:00

      

If you want to find the previous DST change instead of the next one, you can call rules.previousTransition()

instead rules.nextTransition()

.

+2


source


Of course have. There is also more than one. The standard API to use is java.time

.

It is quite obvious that you first need to determine the time zone for which you want to do this.

You tagged your question with gmt and it is very simple: GMT has no daylight saving time (daylight saving time), so there will never be a change in your range. If that's what you meant, you don't need to read anymore.

DST dates are not the same in North America and the EU, and they are completely different in the southern hemisphere. Also, many time zones do not use DST at all. Get your timezone from ZoneId.of()

by specifying a string in the form continent/city

, eg Europe/Stockholm

. It hosts a number of cities, I think they are at least one in every time zone and one in every country. Use ZoneId.getRules()

to get an object ZoneRules

. Please check the documentation for all the things you can do with this object. I think I'll try nextTransistion()

to pass the start date. If I get null

back, there cannot be a range switch (probably no DST applies). If I get it ZoneOffsetTransition

back, use it getInstant()

and check ifInstant

before the end date.



java.time

was described in JSR-310. It is built into Java 8 and later. If you are not using Java 8 yet, use the ThreeTen Backport .

You tagged your question with jodatime and yes, Joda-Time should be an option too.

Please note that Joda-Time is considered to be a pretty much β€œoff the shelf” project. No significant improvements are planned. If you are using Java SE 8, before java.time

(JSR-310).

Quoted from the Joda-Time homepage .

+3


source







All Articles