SimpleDateFormat 返回错误的时间

SimpleDateFormat returning wrong time

我正在尝试使用 SimpleDateFormat 解析 date/time 字符串,但我得到的输出比预期晚了一个小时。

代码

fun formatDate(dateString: String): String {
    val locale = Locale.ENGLISH
    val time = SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZZZ yyyy", locale).parse(dateString)?.time

    return SimpleDateFormat("dd/MM/yyyy HH:mm", locale).format(time)
}

测试

@Test
fun shouldFormatDate() {
    val dateString = "Wed Mar 31 23:13:44 +0000 2010"
    val expected = "31/03/2010 23:13"

    assertThat(formatDate(dateString)).isEqualTo(expected)
}

输出

expected: 31/03/2010 23:13
but was : 01/04/2010 00:13

我尝试使用 ISO-8601 时区格式(X 而不是 Z),但它也不起作用。

任何帮助将不胜感激

您的输入定义了 +0000 的 GMT 时区偏移量 - 对于输入,语言环境时区并不重要。

然而,您的输出使用 ENGLISH 语言环境时区中 2010-03-31 23:12 GMT 生效的时区偏移量。在 2010 年 4 月的第一天,ENGLISH 语言环境使用夏令时,它有一个时区偏移 +0100,意思是比 GMT 晚一个小时。

您在 dateString 中提供的时区不正确,这应该是两个小时后的时区,这两天的总和会有所不同(31/03 和 01/04 之间的差异);因此,为了使您的测试正常进行,您需要将时区从 +0000 更改为 +0200,如下所示:

@Test
fun shouldFormatDate() {
    val dateString = "Wed Mar 31 23:13:44 +0200 2010"
    val expected = "31/03/2010 23:13"

    assertThat(formatDate(dateString)).isEqualTo(expected)
}

UPDATE

dateString 变量中的时区取决于您 运行 此测试所在的本地计算机的时区;这就是 +0100 与你一起工作的原因,但不是我,那是因为我的时区是 GMT+200,而且很可能你在一个地方格林威治标准时间+100.

要验证这一点,请尝试将本地计算机的时区更改为不同于您的时区,然后 运行 测试,您会发现它失败了。

为了让你的测试独立于你电脑的时区,那么你需要明确地设置它;例如,我会选择 "Australia/Sydney" 的时区,即 GMT+11,然后使用 TimeZone.setDefault() 方法覆盖您计算机的时区。

代码

fun formatDate(dateString: String): String {
    TimeZone.setDefault(TimeZone.getTimeZone("Australia/Sydney")) // (GMT+11:00)
    val locale = Locale.ENGLISH
    val time = SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZZZ yyyy", locale).parse(dateString)?.time

    return SimpleDateFormat("dd/MM/yyyy HH:mm", locale).format(time)
}

测试

@Test
fun shouldFormatDate() {
    val dateString = "Wed Mar 31 23:13:44 +1100 2010"
    val expected = "31/03/2010 23:13"

    assertThat(formatDate(dateString)).isEqualTo(expected)
}

你也可能看过this