我有一个对象var phrase = "an important number comes after this: 123456";
var word = "this: ";
var number = phrase.substr(phrase.indexOf(word) + word.length);
// number = 123456
,其中有两个字段:Shift
和startDateTime
来自Joda-Time的endDateTime
。
我的转变包括夏令时英国的变化。它从DateTime
开始,到25/03/2017 13:00
结束(基本上应该在26/03/2017 02:00
结束,但此日期不存在,26/03/2017 01:00
移位+1小时)。根据这个site:
当地标准时间即将到来时 星期日,2017年3月26日,01:00:00时钟转发1小时到 2017年3月26日星期日,当地白天时间02:00:00。
现在,如果我想跟踪员工的工作小时数
endDate
会给我13个小时。
如何使用Joda-Time检测夏令时是否在我的班次持续时间内开始或结束?
答案 0 :(得分:2)
您可以使用org.joda.time.DateTimeZone
课程。它包含有关世界上所有时区的DST更改的信息,因此您无需检测DST更改:如果您正确告知您正在使用的时区,则API会为您完成工作。
当您正在使用英国时区时,您可以直接使用Europe/London
时区 - Continent/City
格式的这些名称来自IANA database,而且'由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
,而且他们都是等同的。
Joda-时间已停止并被新API取代,因此,如果您正在考虑迁移,则可以开始使用新的日期/时间API,但如果您使用的是大代码库Joda或者现在不想迁移它,你可以考虑其余的答案。
无论如何,即使在joda's website中它也说:"请注意,Joda-Time被认为是一个基本上“完成”的项目。没有计划重大改进。如果使用Java SE 8,请迁移到java.time(JSR-310)。" 。*
如果您使用 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs。我不确定它是否已经可用于所有Android版本(但请参阅下面的替代版本)。
如果您正在使用 Java< = 7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,可以使用ThreeTenABP(更多关于如何使用它here)来使用它。
以下代码适用于两者。
唯一的区别是包名称(在Java 8中为java.time
而在ThreeTen Backport(或Android的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
。根据{{3}},between
和until
是等效的,javadoc。使用Duration
也是等效的,因为它使用它们之间的纳秒并将其转换为小时。
答案 1 :(得分:0)
当您使用TimeZone ID时,会自动处理日光。