我有一个对象Shift,有两个字段:startDateTime和endDateTime作为DateTime来自Joda-Time。
我的转变包括日照节约英国的变化。它从25/03/2017 13:00开始,以26/03/2017 02:00结束(基本上应该以26/03/2017 01:00结束,但这个日期不存在,endDate被移到+1小时)。根据这个站点
当当地标准时间即将到达2017年3月26日星期日时,01:00时钟被调到2017年3月26日星期日1小时,而不是当地白天时间02:00。
现在,如果我想跟踪员工的工作时数,new Duration(startDateTime, endDateTime).toStandardHours().getHours()会给我13个小时。
如何检测日照节约是否开始或结束在我的班次使用Joda-Time?
发布于 2017-06-18 23:27:34
您可以使用org.joda.time.DateTimeZone类。它拥有世界上所有时区的DST更改信息,因此您不需要检测DST更改:如果您正确地告知您使用的是哪个时区,则API将为您完成任务。
当您使用英国时区时,您可以直接使用Europe/London时区-- Continent/City格式的这些名称来自于IANA数据库,Joda-Time、Java和许多其他API都使用它。您可以通过调用DateTimeZone.getAvailableIDs()获得所有时区的列表。
当您使用DateTimeZone时,它已经包含了历史期间的所有DST移位,所以API为您做了所有的数学运算。您只需在此时区创建DateTime实例:
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移位)。
您还可以使用:
duration.toStandardHours().getHours()或者org.joda.time.Hours类
Hours.hoursBetween(start, end).getHours()它们都返回12,它们都是等价的。
Java新日期/时间API
Joda --它正在被停止使用,并被新的API所取代,所以如果您正在考虑迁移,您可以开始使用新的日期/时间API,但是如果您有一个使用Joda的大型代码库,或者现在不想迁移它,那么您可以不考虑其余的答案。
无论如何,即使在尤达的网站中,它也说:“注意到Joda-Time被认为是一个基本”完成“的项目。没有重大的改进计划。如果使用Java 8,请迁移到java.time (JSR-310)。”.*。
如果您使用的是Java 8,请考虑使用新java.time API。容易点,比旧的APIs更少被窃听,更容易出错。。我不确定它是否已经适用于所有的Android版本(但请看下面的替代方案)。
如果您使用的是 <= 7,您可以使用ThreeTen Backport,这是Java 8的新日期/时间类的一个很好的后端。对于Android,有一种使用ThreeTenABP的方法(更多关于如何使用这里)。
下面的代码对两者都适用。唯一的区别是包名(在Java 8中是java.time,而在ThreeTen Backport (或安卓的ThreeTenABP)是org.threeten.bp),但是类和方法名称是相同的。
新API还使用IANA时区名称,并包含有关DST移位的相同历史信息(以获得所有时区的列表:ZoneId.getAvailableZoneIds())。代码非常相似,也有不止一种方法可以得到不同的结果:
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的说法,between和until是等价的,因为第一个只是内部调用第二个。使用Duration也是等价的,因为它使用它们之间的纳秒并将它们转换为小时。
发布于 2018-07-04 17:24:20
当您使用TimeZone ID时,会自动处理日光。
https://stackoverflow.com/questions/44617846
复制相似问题