Duration with daylight saving

不羁的心 提交于 2019-12-06 11:33:54

You can use org.joda.time.DateTimeZone class. It has information about DST changes for all timezones in the world, so you don't need to detect the DST change: if you correctly inform which timezone you're using, the API does the job for you.

As you're working with UK timezone, you can use directly the Europe/London timezone - these names in the format Continent/City comes from the IANA database, and it's used by Joda-Time, Java and many other APIs. You can get a list of all timezones by calling DateTimeZone.getAvailableIDs().

When you use a DateTimeZone, it already contains all the DST shifts during history, so the API does all the math for you. You just need to create your DateTime instances at this timezone:

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;

// London timezone - it contains all info about DST shifts
DateTimeZone london = DateTimeZone.forID("Europe/London");

// Start on 25/03/2017 13:00
DateTime start = new DateTime(2017, 3, 25, 13, 0, london);
// ends on 26/03/2017 02:00
DateTime end = new DateTime(2017, 3, 26, 2, 0, london);

// get the difference between start and end
Duration duration = new Duration(start, end);
System.out.println(duration.getStandardHours()); // 12

The output will be 12 (the API uses the information of the DateTime's timezones to calculate the difference, including DST shifts).

You can also use:

duration.toStandardHours().getHours()

Or the class org.joda.time.Hours:

Hours.hoursBetween(start, end).getHours()

All of them return 12, and they're all equivalent.


Java new Date/Time API

Joda-Time it's being discontinued and replaced by the new APIs, so if you're considering a migration, you can start using the new Date/Time API, but if you have a big codebase using Joda or don't want to migrate it now, you can desconsider the rest of the answer.

Anyway, even in joda's website it says: "Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".*

If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs. I'm not sure if it's already available to all Android versions (but see the alternative below).

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

The code below works for both. The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.

The new API also uses IANA timezones names and contains the same historical information about the DST shifts (to get a list of all timezones: ZoneId.getAvailableZoneIds()). The code is very similar, and there's also more than one way to get the difference:

import java.time.Duration;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;

// London timezone
ZoneId london = ZoneId.of("Europe/London");

// Start on 25/03/2017 13:00
ZonedDateTime start = ZonedDateTime.of(2017, 3, 25, 13, 0, 0, 0, london);
// ends on 26/03/2017 02:00
ZonedDateTime end = ZonedDateTime.of(2017, 3, 26, 2, 0, 0, 0, london);

// get the difference in hours
System.out.println(ChronoUnit.HOURS.between(start, end)); // 12

// get the duration in hours
Duration duration = Duration.between(start, end);
System.out.println(duration.toHours()); // 12

// using until() method
System.out.println(start.until(end, ChronoUnit.HOURS)); // 12

All the three methods above (ChronoUnit.HOURS.between(), duration.toHours() and start.until()) return 12. According to javadoc, between and until are equivalent, as the first just internally calls the second. Using a Duration is also equivalent, as it uses the nanoseconds between them and convert it to hours.

  1. You should use TimeZone ID e.g., "Europe/London"
  2. Convert start and end time into GMT
  3. Now find the duration from GMT start and end times

Daylight is automatically handled when u use TimeZone IDs.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!