【发布时间】:2012-10-16 09:26:44
【问题描述】:
我们在应用程序中使用固定的时间段。当用户添加一个新的时段时,默认应该是从早上 6:00 到第二天早上 6:00。
通常是 24 小时,但有一个问题:当执行夏令时更改时,该时间段的长度会发生变化。例如:
10 月 27 日上午 6 点至 10 月 28 日上午 6 点。在此期间执行从 CEST 到 CET 时区的转换。因此,此期间包含 25 小时:
From 27 October 6:00 AM to 28 October 3:00 AM - there are 21 hours
at 3:00 am the time is shifted back by 1 hour, so there are 4 hours until 28 October 6:00 AM.
我们遇到了这个问题,并试图编写一个单元测试来防止它再次出现。测试在我们的机器上成功通过,但在 CI 服务器上失败(它在另一个时区)。
问题是:我们如何能够独立于机器的时区设计我们的单元测试?
目前,小时跨度的计算使用Joda-Time:
if ((aStartDate == null) || (aEndDate == null)) {
return 0;
}
final DateTime startDate = new DateTime(aStartDate);
final DateTime endDate = new DateTime(aEndDate);
return Hours.hoursBetween(startDate, endDate).getHours();
在我们这边通过但在 CI 服务器上失败的单元测试:
Calendar calendar = Calendar.getInstance();
calendar.set(2012, Calendar.OCTOBER, 27, 6, 0);
startDate= calendar.getTime();
calendar.set(2012, Calendar.OCTOBER, 28, 6, 0);
endDate= calendar.getTime();
我们尝试为日历使用时区:
TimeZone.setDefault(TimeZone.getTimeZone(TimeZone.getTimeZone("GMT").getID()));
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(TimeZone.getTimeZone("GMT").getID()));
calendar.set(2012, Calendar.OCTOBER, 27, 6, 0, 0);
startDate= calendar.getTime();
calendar.set(2012, Calendar.OCTOBER, 28, 6, 0, 0);
endDate= calendar.getTime();
但在这种情况下,结果 startDate 是 10 月 27 日 CEST 9:00,endDate 是 10 月 28 日 8:00 CET,所以即使在我们这边测试也失败了。
提前谢谢你。
【问题讨论】:
-
aStartDate和aEndDate是什么?目前尚不清楚您要尝试获得什么结果,或者您想要使用哪个时区(假设您曾在一个地方讨论过 CST/CEST,并且GMT 在另一个)。您希望它有什么用途:TimeZone.getTimeZone(TimeZone.getTimeZone("GMT").getID())? -
@JonSkeet 关于示例代码 - 我只是想得到任何结果,所以现在对我来说没有多大意义。关于预期结果 - 我们希望确保在 DST 轮班时 - 1“天”的长度为 23 或 25 小时,具体取决于用户的时区。