SimpleDateFormat 导致时间不正确

SimpleDateFormat results in incorrect time

我有以下代码

    protected void amethod1() {
    String strDate = "Thu May 18 16:24:59 UTC 2017";
    String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
    DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);

    Date formattedDate = null;
    try {
        formattedDate = dateFormat.parse(strDate);
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

formattedDate 的结果值为 - "Thu May 18 11:24:59 CDT 2017" 。

我正在芝加哥测试这段代码,当地时区是 CDT。
我无法理解为什么时间值会从 16:24:59 变为 11:24:59。我是否遗漏了定义的日期格式?

Class Date 根本不包含任何时区。自格林威治标准时间 01.01.1970 00:00:00 以来,这只是几毫秒。如果您尝试查看 formattedDate 包含 System.out.println 或调试器的内容,您将获得本地时区的格式化日期。 11:24:59 CDT16:24:59 UTC 是同一时间,所以结果是正确的。

Is java.util.Date using TimeZone?

为了更好地管理时间和时区,最好使用jodatimeJava 8 Time API

SimpleDateFormat myFmt=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date now=new Date(); System.out.println(myFmt.format(now)); 希望能帮到你。如果可以,请adopt.Thank你

formattedDate 的结果值为 - "Thu May 18 11:24:59 CDT 2017"。 为什么? 因为你的时区 运行 -5 小时从 UTC 时间你会在下面找到 link wiki 时区缩写,如果你想要在相同时区的结果需要在格式化程序中指定时区希望你能得到我的关注

https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations

public static void amethod1() {
        String strDate = "Thu May 18 16:24:59 UTC 2017";
        String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
        SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

        Date formattedDate = null;
        try {
            formattedDate = dateFormat.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        System.out.println("formattedDate: "+dateFormat.format(formattedDate));

    }

您指定了时区,这就是为什么在解析当前时区(您所在的位置)的时间后,SimpleDateFormat 设置 UTC 时区。当您尝试输出日期时,它会显示在您当前的时区

看来您在格式化日期时也需要指定时区,例如。 .TimeZone.setDefault(TimeZone.getTimeZone("PST")); 看看这个讨论 TimeZone

首先,您得到的时间是正确的。当夏令时在芝加哥使用时(即 5 月 18 日),UTC 时间为 16:24:59 时为 11:24:59。所以你的 Date 值代表同一个时间点。这就是您对 Date.

的全部期望

我了解到您不仅需要时间点,还需要 UTC 时区。由于,我只想填写详细信息:

    DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern(dateFormatStr, Locale.US);
    ZonedDateTime dateTime = ZonedDateTime.parse(strDate, parseFormatter);

结果是

2017-05-18T16:24:59Z[UTC]

如果您总是想要 UTC 时区,Instant class 正好适合它,因此您可能想要转换成它:

    Instant instant = dateTime.toInstant();

通俗地说,瞬间总是在 UTC。

日期的输出取决于指定的格式,您可以在其中指定时区,如下例所示:

protected void amethod2() {
    String strDate = "Thu May 18 16:24:59 UTC 2017";
    String dateFormatStr = "EEE MMM dd HH:mm:ss zzz yyyy";
    DateFormat dateFormat = new SimpleDateFormat(dateFormatStr);

    Date formattedDate = null;
    try {
        formattedDate = dateFormat.parse(strDate);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    System.out.println("Date: " + formattedDate);
    // Thu May 18 17:24:59 BST 2017, BST is my system default timezone

    // Set the time zone to UTC for the calendar of dateFormat
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    System.out.println("Date in timezone UTC: " + dateFormat.format(formattedDate));
    // Thu May 18 16:24:59 UTC 2017

    // Set the time zone to America/Chicago
    dateFormat.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
    System.out.println("Date in timezone America/Chicago: " + dateFormat.format(formattedDate));
    // Thu May 18 11:24:59 CDT 2017
}

至于例子中的"UTC"、"America/Chicago"等ID,你可以通过TimeZone.getAvailableIDs()获取完整的列表。大家可以打印出来看看:

Arrays.stream(java.util.TimeZone.getAvailableIDs()).forEach(System.out::println);

你将拥有:

Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
Africa/Bamako
Africa/Bangui
Africa/Banjul
Africa/Bissau
Africa/Blantyre
...