将指定时区的日期字符串转换为GMT

时间:2016-03-02 16:54:11

标签: java timezone

我有以下代码从给定的日期字符串中解析出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接受我传递的偏移量,而不是它是聪明的并使用自己的一组时区规则来执行转换?

2 个答案:

答案 0 :(得分:1)

AEST时区现在是+11小时(DST),因此基本上忽略了字符串+1000并且应用了-11小时偏移量

您可以从测试中删除符号时区名称(AEST),仅在+1000上转发或调整您的测试

答案 1 :(得分:0)

AESTAustralia/Sydney,观察夏令时,2016年,DST于4月3日结束,10月2日再次开始。

这意味着03 Mar 2016位于夏令时,+1100,而不是+1000

ZonedDateTime.parse返回:

2016-03-03T02:42+11:00[Australia/Sydney]

转换为GMT会为您提供:

2016-03-02T15:42Z[GMT]

调试代码会向您显示此信息。我刚刚为dateTimedateTimeInGMT添加了打印语句来查看它。