夏令时 [英] Duration with daylight saving

查看:224
本文介绍了夏令时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象 Shift ,有两个字段: startDateTime endDateTime 作为Joda-Time的 DateTime

I have an object Shift, with two fields: startDateTime and endDateTime as DateTime from Joda-Time.

我的工作包括英国夏令时的更改。它开始于 25/03/2017 13:00 ,结束于 26/03/2017 02:00 (基本上应该以 26/03/2017 01:00 结尾,但是该日期不存在,并且 endDate 已移动+ 1小时)。根据该网站

And my shift includes Daylight Saving UK change. It starts on 25/03/2017 13:00 and ends on 26/03/2017 02:00 (basically should end on 26/03/2017 01:00, but this date does not exists, and endDate is shifted +1 hour). According to this site:


2017年3月26日星期日当地标准时间即将达到
时,将2017年3月26日星期日01:00:00时钟向前调整1小时至
,而是改为当地的夏令时02:00:00。

When local standard time was about to reach Sunday, 26 March 2017, 01:00:00 clocks were turned forward 1 hour to Sunday, 26 March 2017, 02:00:00 local daylight time instead.

现在,如果我想跟踪员工的工作时间
new Duration(startDateTime,endDateTime).toStandardHours()。getHours()会给我13个小时。

Now if I want to track the number of hours worked by a employee new Duration(startDateTime, endDateTime).toStandardHours().getHours() will give me 13 hours.

如何使用Joda-Time检测夏令时是在我的上班时间开始还是结束?

How can I detect if Daylight Saving starts or ends on my shift duration using Joda-Time?

推荐答案

您可以使用 org.joda.time.DateTimeZone 类。它包含有关全球所有时区的DST更改的信息,因此您无需检测DST更改:如果您正确告知所使用的时区,则API会为您完成工作。

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.

在使用英国时区时,可以直接使用欧洲/伦敦时区-这些名称的格式为 Continent /城市来自 IANA数据库,它由Joda-时间,Java和许多其他API。您可以通过调用 DateTimeZone.getAvailableIDs()来获取所有时区的列表。

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().

使用时DateTimeZone ,它已经包含历史记录中的所有DST偏移,因此API会为您完成所有数学运算。您只需要在此时区创建您的 DateTime 实例:

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

输出将为 12 (API使用 DateTime 的时区信息来计算时差,包括DST偏移)。

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

您还可以使用:

duration.toStandardHours().getHours()

或类 org.joda.time.Hours

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

所有返回 12 ,它们都是等效的。

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

Joda-Time,该产品已停产并由新的API取代,因此,如果您考虑进行迁移,则可以开始使用新的日期/时间API,但是如果您使用Joda的代码库很大,或者现在不想迁移,则可以考虑使用剩下的答案。

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.

无论如何,即使在 joda的网站它说:"请注意,Joda-Time是consi被认为是一个完成的项目。没有计划进行重大增强。如果使用Java SE 8,请迁移到java.time(JSR-310)。 。*

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).".*

如果您使用的是 Java 8 >,请考虑使用新的java.time API 。与旧的API相比,更少的错误和更少的错误 。我不确定它是否已经适用于所有Android版本(但请参见下面的替代方法。)。

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).

如果您使用的是 Java< = 7 ,您可以使用 ThreeTen Backport ,它是Java 8的新日期/时间类的绝佳反向端口。对于 Android ,可以使用 ThreeTenABP 在此)。

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).

下面的代码对两者都适用。
唯一的区别是软件包名称(在Java 8中为 java.time ,在ThreeTen Backport(或Android的ThreeTenABP)中为 org。 threeten.bp ),但类和方法的名称是相同的。

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.

新API也使用IANA时区名称并包含关于DST偏移的相同历史信息(以获取所有时区的列表: ZoneId.getAvailableZoneIds())。代码非常相似,并且也有不止一种方法可以实现区别:

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

以上所有三种方法( ChronoUnit.HOURS.between() duration.toHours() start.until())返回 12 。根据 javadoc ,和直到之间的是等效的,< a href = http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/43cb25339b55/src/share/classes/java/time/temporal/ChronoUnit.java#l270 rel = nofollow noreferrer >第一个只是内部调用第二个。使用持续时间也是等效的,因为它使用它们之间的纳秒级并将其转换为小时。

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.

这篇关于夏令时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆