以正确的格式将 LocalDate 解析为 ZonedDateTime

Parsing LocalDate to ZonedDateTime in correct format

鉴于:

public static void main(String[] args) {

   String dateString = "2018-07-30T13:36:17.820";

    DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
            .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");

    LocalDate date = LocalDate.parse(dateString, DATE_TIME_FORMATTER);

    ZonedDateTime zonedDateTime = date.atStartOfDay((ZoneOffset.UTC));

    System.out.println(zonedDateTime);
}

并输出:

2018-07-30T00:00Z

...打印秒的模式是什么?毫无疑问是个愚蠢的问题,但让我有点抓狂

我需要:

2018-07-30T00:00:00Z

LocalDate 将只保留日期。您需要解析 LocalDateTime 并转换为 ZonedDateTime,您将获得预期的秒数。

    var dateString = "2018-07-30T13:36:17.820";
    var format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
    var localDate = LocalDateTime.parse(dateString, format);
    var zone = ZoneId.of( "America/Montreal" );
    var zonedDateTime = localDate.atZone(zone);
    System.out.println(zonedDateTime);

我把java.time.LocalDate改成了java.time.LocalDate时间,如果你还想显示秒。

package com.test;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class DateFormatter {

    public static void main(String[] args) {

        String dateString = "2018-07-30T13:36:17.820";

        DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
                .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");

        LocalDateTime date = LocalDateTime.parse(dateString, DATE_TIME_FORMATTER);

        ZonedDateTime zonedDateTime = date.atZone(ZoneOffset.UTC);


        System.out.println(zonedDateTime);
    }
}

输出为:

2018-07-30T13:36:17.820Z

您将需要执行以下步骤:

  • String 解析为 LocalDateTime 因为它包含日期和时间
  • 仅提取日期
  • 通过添加一天的开始 (LocalTime.MIN = 00:00:00) 和 ZoneOffset.UTC
  • 从中创建一个 ZonedDateTime

这段代码可以做到:

public static void main(String[] args) {
    String dateString = "2018-07-30T13:36:17.820";
    // parse a LocalDateTime
    LocalDateTime localDateTime = LocalDateTime.parse(dateString);
    // extract the date part
    LocalDate localDate = localDateTime.toLocalDate();
    // make it a ZonedDateTime by applying a ZoneId
    ZonedDateTime zonedDateTime = ZonedDateTime.of(localDate, LocalTime.MIN, ZoneOffset.UTC);
    // print the result
    System.out.println(zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}

输出是

2018-07-30T00:00:00Z

有几种方法可以做到这一点,这只是其中一种,它与大多数其他答案(和评论 :-) 略有不同)。

tl;博士

你在错误的地方使用了错误的东西。

  1. 您不需要显式 DateTimeFormatter 来解析 2018-07-30T13:36:17.820,因为它已经在 ISO 8601 format which is also the default format used by LocalDateTime#parse. Moreover, this string has date and time instead of just date; therefore, it makes more sense to parse it into LocalDateTime instead of LocalDate. You can always get LocalDate from LocalDateTime using LocalDateTime#toLocalDate.
  2. 时间部分的 ZonedDateTime#toString uses the LocalDateTime#toString which in turn uses LocalTime#toString 如果它们为零,则省略秒和秒的小数部分。如果您需要零秒和小数秒的字符串,则需要使用 DateTimeFormatter.

演示:

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String args[]) {
        String dateString = "2018-07-30T13:36:17.820";

        LocalDateTime localDateTime = LocalDateTime.parse(dateString);// You do not need a DateTimeFormatter here

        ZonedDateTime zonedDateTime = localDateTime.toLocalDate().atStartOfDay(ZoneOffset.UTC);

        // Print zonedDateTime.toString()
        System.out.println(zonedDateTime);

        // Custom format
        final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
        System.out.println(DATE_TIME_FORMATTER.format(zonedDateTime));
    }
}

输出:

2018-07-30T00:00Z
2018-07-30T00:00:00.000

Trail: Date Time.

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