首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >夏令期间

夏令期间
EN

Stack Overflow用户
提问于 2017-06-18 17:48:44
回答 2查看 1.2K关注 0票数 3

我有一个对象Shift,有两个字段:startDateTimeendDateTime作为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?

EN

回答 2

Stack Overflow用户

发布于 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实例:

代码语言:javascript
运行
复制
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移位)。

您还可以使用:

代码语言:javascript
运行
复制
duration.toStandardHours().getHours()

或者org.joda.time.Hours

代码语言:javascript
运行
复制
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())。代码非常相似,也有不止一种方法可以得到不同的结果:

代码语言:javascript
运行
复制
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的说法,betweenuntil是等价的,因为第一个只是内部调用第二个。使用Duration也是等价的,因为它使用它们之间的纳秒并将它们转换为小时。

票数 2
EN

Stack Overflow用户

发布于 2018-07-04 17:24:20

  1. 您应该使用TimeZone ID,例如“欧洲/伦敦”
  2. 将开始和结束时间转换为格林尼治标准时间
  3. 现在找到从格林尼治时间开始和结束时间的持续时间。

当您使用TimeZone ID时,会自动处理日光。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44617846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档