Java SimpleDateFormat 为不同的日期提供不同的时区

问题描述 投票:0回答:3

我在解析日期时有一个奇怪的行为。给定

DateFormat sdf= new SimpleDateFormat("dd/MM/yyyy");

sdf.parse("25/10/2014")
返回 2014 年 10 月 25 日 00:00:00 BST

同时

sdf.parse("27/10/2014")
返回 2014 年 10 月 27 日 00:00:00 GMT

我发现这是因为夏令时的变化,但我肯定希望同一个解析器返回相同的时区。还是我错了?

java simpledateformat
3个回答
5
投票

根据维基百科关于 英国夏令时间

的文章

在英国夏令时 (BST) 期间,英国的民用时间比格林威治标准时间 (GMT) 提前一小时,因此晚上的日光较多,早晨的日光较少

BST 从 3 月最后一个星期日 01:00 GMT 开始,到 10 月最后一个星期日 01:00 GMT (02:00 BST) 结束。

2014年10月的最后一个周日是26号。因此,时区从英国夏令时间更改为英国观察到的 GMT。

默认时区是您的系统时区,因此当它更改时您的解析器也会更改。


0
投票

来自

SimpleDateFormat#parse(String ParsePosition)
的文档:

TimeZone
值可能会被覆盖,具体取决于给定的 模式和
text
中的时区值。任意
TimeZone
之前通过调用
setTimeZone()
设置的值 可能需要恢复以进行进一步操作。

所以:不,解析器并不总是返回相同的时区。


0
投票

我发现这是因为夏令时的变化,但我肯定 期望同一个解析器返回相同的时区。或者 我错了吗?

BST 更合适地指定 +01:00

时区偏移
,而不是时区。时区是
Europe/London

java.time

顺便说一下,2014 年 3 月,Java 8 引入了现代的

java.time
日期时间 API,它取代了 容易出错的旧版
java.util
日期时间 API
。任何新代码都应使用
java.time
API*

使用现代日期时间 API 的解决方案

如果您可以通过解析这些日期文本字符串(即 25/10/2014 和 27/10/2014)并添加 ZonedDateTime

 的时区来创建 
Europe/London
,那么当您打印它们时,您会看到差异默认格式。

2014 年英国夏令时什么时候结束?

如本页所示,于 10 月 26 日结束 https://www.timeanddate.com/time/change/uk/london?year=2014.

演示:

public class Main {
    static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/uuuu");

    public static void main(String[] args) {
        ZoneId zoneId = ZoneId.of("Europe/London");

        System.out.println(ZonedDateTime.of(LocalDate.of(2014, Month.OCTOBER, 25), LocalTime.MIN, zoneId));
        System.out.println(ZonedDateTime.of(LocalDate.of(2014, Month.OCTOBER, 27), LocalTime.MIN, zoneId));
    }
}

输出:

2014-10-25T00:00+01:00[Europe/London]
2014-10-27T00:00Z[Europe/London]

在线演示

Z
指定
+00:00
的时区偏移量。

Trail:日期时间了解有关现代日期时间 API 的更多信息。


* 如果您收到

java.util.Date
的实例,请使用
java.time.Instant
 将其转换为 
Date#toInstant
,并根据您的要求从中派生
java.time
的其他日期时间类。

© www.soinside.com 2019 - 2024. All rights reserved.