Java 8 localdatetime vs Date

ano*_*ous 2 java datetime java-8

我有一个字符串2017-07-31T01:01:00-07:00,我试图解析它到目前为止和CST时区.当我使用Date和Java 8 ZonedDateTime解析此字符串时,我得到了不同的结果.我不知道为什么会发生这种情况以及我做错了什么.

    String dateStr = "2017-07-31T01:01:00-07:00";
    LocalDateTime time = null;
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss-hh");

    String[] dateArray = dateStr.split("-");
    String[] timeZones = TimeZone
            .getAvailableIDs(TimeZone.getTimeZone("GMT-" + dateArray[dateArray.length - 1]).getRawOffset());
    format.setTimeZone(TimeZone.getTimeZone(timeZones[0]));
    Date dateObj = null;
    try {
        dateObj = format.parse(dateStr);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    time = dateObj.toInstant().atZone(TimeZone.getTimeZone("CST").toZoneId()).toLocalDateTime();
    ZonedDateTime time2 = ZonedDateTime.parse(dateStr).toInstant().atZone(TimeZone.getTimeZone("CST").toZoneId());
    System.out.println(time);
    System.out.println(time2.toLocalDateTime());
Run Code Online (Sandbox Code Playgroud)

And*_*eas 5

您不应该自己解析时区偏移量.只需使用X模式:

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX")
Run Code Online (Sandbox Code Playgroud)

你不应该使用时区CST,因为这是不明确的(中央标准时间,中国标准时间,古巴标准时间).使用America/Chicago(我认为这就是你的意思).

因此,要使用旧API和新API解析日期字符串:

String dateStr = "2017-07-31T01:01:00-07:00";

// Using Date
SimpleDateFormat parseFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = parseFormat.parse(dateStr);

SimpleDateFormat printFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm");
printFormat.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
System.out.println(printFormat.format(date));

// Using ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateStr);
zonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("America/Chicago"));
System.out.println(zonedDateTime.toLocalDateTime());
Run Code Online (Sandbox Code Playgroud)

产量

2017-07-31T03:01
2017-07-31T03:01
Run Code Online (Sandbox Code Playgroud)

如果要查看时区,可以执行以下操作:

String dateStr = "2017-07-31T01:01:00-07:00";

// Using Date
SimpleDateFormat parseFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = parseFormat.parse(dateStr);

SimpleDateFormat printFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm XXX z");
printFormat.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
System.out.println(printFormat.format(date));

// Using ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateStr);

DateTimeFormatter printFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm XXX z")
                                                    .withZone(ZoneId.of("America/Chicago"));
System.out.println(zonedDateTime.format(printFormatter));
Run Code Online (Sandbox Code Playgroud)

产量

2017-07-31T03:01 -05:00 CDT
2017-07-31T03:01 -05:00 CDT
Run Code Online (Sandbox Code Playgroud)

请注意第一个示例如何更改ZonedDateTime时区,将其转换为a LocalDateTime,然后在没有格式化程序的情况下打印,而在第二个示例中,DateTimeFormatter设置为在特定时区中格式化值,类似于SimpleDateFormat执行此操作的方式.只是不同的方法来实现相同的结果.