我有以下代码从给定的日期字符串中解析出ZonedDateTime
对象,输入字符串的格式如下:
"Thu, 03 Mar 2016 02:42:00 +1000 (AEST)"
我的解析代码是这样的:
public ZonedDateTime parseDate(String dateString) throws Exception {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ccc, dd MMM yyyy HH:mm:ss Z (z)");
ZonedDateTime dateTime = ZonedDateTime.parse(dateString, formatter);
ZoneId gmt = ZoneId.of("GMT");
ZonedDateTime dateTimeInGMT = dateTime.withZoneSameInstant(gmt);
return dateTimeInGMT;
}
我有这个单元测试:
@Test
public void shouldParseTimezone() throws Exception {
MailFileParserJava parser = new MailFileParserJava();
String aestDateTime = "Thu, 03 Mar 2016 02:42:00 +1000 (AEST)";
ZonedDateTime aestZone = parser.parseDate(aestDateTime);
assertThat(aestZone.getDayOfMonth(), is(2));
assertThat(aestZone.getHour(), is(16));
}
但是我的单元测试在 getHour() 断言上失败 -
Expected: is <16>
but: was <15>
我不明白出了什么问题,如果我有凌晨 2:42 的时间,并且我减去 +10 小时的偏移量,那么我应该得到下午 4:42 的结果(即小时是 16)。
我将字符串转换为ZonedDateTime
的方式是否有问题,或者我的代码有其他问题?
编辑:
好的,看起来我正在做的时区转换工作忽略了我传入的时区偏移量,并考虑了给定日期的实际时区(即现在它是澳大利亚东部的夏令时,所以实际偏移量是 +1100 而不是 +1000)。
现在我的问题是,我怎样才能让 Java 接受我传递的偏移量,而不是它很聪明并使用自己的时区规则集来执行转换?
AEST
时区现在是 +11 小时 (DST),因此基本上忽略字符串+1000
并应用 -11 小时偏移量
您可以从测试中删除符号时区名称 (AEST) 并仅在+1000
上中继,也可以调整测试
AEST
是Australia/Sydney
,它遵守夏令时,对于 2016 年,DST 于 4 月 3 日结束,并于 10 月 2 日重新开始。
这意味着03 Mar 2016
在 DST 中,这是 +1100
,而不是 +1000
。
ZonedDateTime.parse
回报:
2016-03-03T02:42+11:00[Australia/Sydney]
转换为格林威治标准时间可为您提供:
2016-03-02T15:42Z[GMT]
调试代码会显示这一点。我只是为dateTime
和dateTimeInGMT
添加了打印语句以查看它。