SimpleDateFormat导致错误的时间

时间:2017-05-23 09:47:59

标签: java simpledateformat date-format

我有以下代码

    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的结果值是 - “5月18日星期四18:24:59 CDT 2017”。

我在芝加哥测试此代码,当地时区是CDT 我无法理解为什么时间值从16:24:59变为11:24:59,尽管如此。我错过了定义的日期格式吗?

7 个答案:

答案 0 :(得分:3)

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

Is java.util.Date using TimeZone?

最好使用16:24:59 UTCjodatime以便更好地管理时间和时区。

答案 1 :(得分:2)

首先,你得到了正确的时间。当芝加哥​​使用夏令时(5月18日)时,UTC时间为16:24:59,时间是11:24:59。因此,您的Date值代表相同的时间点。您可以从Date获得所有这些。

据我所知,您不仅需要时间点,还需要UTC时区。自Axel P has already recommended Java 8 date and time API起,我只想填写详细信息:

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

结果是

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

如果您一直想要UTC时区,那么Instant类就适合它,所以您可能希望转换为它:

    Instant instant = dateTime.toInstant();

通常说,Instants总是使用UTC。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

formattedDate的结果值是 - &#34;周五5月18日11:24:59 CDT 2017&#34; 。 为什么?因为您的时区从UTC时间开始运行-5小时,您会在下面的链接wiki时区缩写中找到,如果您想要在同一时区得到结果,您需要在formater中指定时区希望您能得到我的关注

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));

    }

答案 4 :(得分:0)

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

答案 5 :(得分:0)

在格式化日期时,您似乎还需要指定TimeZone。 。TimeZone.setDefault(TimeZone.getTimeZone("PST")); 看一下这个讨论TimeZone

答案 6 :(得分:0)

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

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
}

对于ID,例如示例中的“UTC”和“America / Chicago”,您可以通过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
...