【问题标题】:Parsing LocalDate to ZonedDateTime in correct format以正确的格式将 LocalDate 解析为 ZonedDateTime
【发布时间】:2021-04-26 13:28:36
【问题描述】:

给定:

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

【问题讨论】:

  • 只需使用DateTimeFormatter。你清楚地知道如何使用它......
  • 另外请注意,如果您只想将 ZDT 的时间部分设置为 00:00,您可以使用truncatedTo(ChronoUnit.DAYS)。无需先解析为LocalDate

标签: java java-time datetimeformatter


【解决方案1】:

我将 java.time.LocalDate 更改为 java.time.LocalDateTime,如果您还想显示秒数,则需要它。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      你将不得不走几步:

      • 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
      

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

      【讨论】:

      • 谢谢,我快到了,只是看不到 :)
      【解决方案4】:

      tl;博士

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

      1. 您不需要显式地使用DateTimeFormatter 来解析2018-07-30T13:36:17.820,因为它已经采用ISO 8601 格式,这也是LocalDateTime#parse 使用的默认格式。此外,这个字符串有日期和时间,而不仅仅是日期;因此,将其解析为LocalDateTime 而不是LocalDate 更有意义。您始终可以使用LocalDateTime#toLocalDateLocalDateTime 获取LocalDate
      2. ZonedDateTime#toString 使用LocalDateTime#toString,而LocalTime#toString 又使用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 的更多信息。

      【讨论】:

        猜你喜欢
        • 2020-12-15
        • 1970-01-01
        • 2021-07-17
        • 2015-11-07
        • 2023-03-09
        • 2017-05-31
        • 1970-01-01
        • 2019-10-05
        • 2015-07-06
        相关资源
        最近更新 更多