为什么在 1971 年 11 月 1 日之前的日期,在 java.util.Date 中添加一小时?

2022-09-02 20:04:53

以下代码似乎演示了 java.util.Date 中的一个错误,如果本地时钟设置为 GMT 且打开 DST 调整,并且时间早于 1971 年 11 月 1 日,则会添加一个小时。我的第一个假设总是我弄错了。任何人都可以看到哪里出了问题(或者这真的是一个Java错误)?1971年11月1日有什么意义?

import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;

class JavaUtilDateBug
{
    private static void demo() throws Exception
    {
        // UK developers usually have the clock on their development machines set
        // to "Europe/London" (i.e. GMT with daylight saving). Set it explicitly 
        // here so readers in other countries can see the problem too.
        TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
        Locale.setDefault(Locale.ENGLISH);

        SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
        String strJan1st1970Expected = "Thu Jan 01 00:00:00 GMT 1970";
        String strJan1st1970Actual = dateFormat.parse(strJan1st1970Expected).toString();
        System.out.println("strJan1st1970Actual: " + strJan1st1970Actual); // -> "Thu Jan 01 01:00:00 GMT 1970"
        boolean jvmHasDateBug = !strJan1st1970Expected.equals(strJan1st1970Actual);
        System.out.println("jvmHasDateBug: " + jvmHasDateBug); // -> true

        // The anomaly only seems to affect times before 1 Nov 1971.
        final String strNov1st1971 = "Mon Nov 01 00:00:00 GMT 1971";
        assert strNov1st1971.equals(dateFormat.parse(strNov1st1971).toString());
    }

    public static void main(String[] args)
    {
        try
        {
            demo();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

我的 Java 环境:

  java version "1.6.0_13"
  Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
  Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)

答案 1

在1968年10月27日至1971年10月31日之间对英国标准时间进行了审判,我怀疑这是导致此问题的原因。

这里有一些试验的细节:

http://en.wikipedia.org/wiki/British_Summer_Time#Single.2FDouble_Summer_Time

1970 年 1 月 1 日,欧洲/伦敦的时区是英国标准时间 (GMT+1),因此当您使用 a 解析 Jan 01 00:00:00 GMT 1970 时,它会生成正确的 epoch 值,该值等于 1970 年 1 月 1 日 01:00:00 1970 年 1 月 1 日。java.text.SimpleDateFormat

然后,由于 的蹩脚性,当您调用它时,它使用当前本地的默认时区,截至目前,它已更改为GMT,并且您得到Jan 01 01:00:00 GMT 1970。java.util.Datejava.util.Date.toString()


答案 2

这是区域设置。从 http://en.wikipedia.org/wiki/British_Summer_Time

英国标准时间计划在1968年10月27日至1971年10月31日期间进行了试验,当时英国全年都保持在GMT+1。