首页 > 解决方案 > 在 Spring Boot Java 中将 GMT 格式字符串转换为日期时间

问题描述

My Mongo Input Source data is 2020-04-14 00:00:00.0000000 (GMT-04:00), 
Data Type String
Error: Caused by: java.time.format.DateTimeParseException: Text '' could not be parsed at index 0
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) ~[na:1.8.0_222]

我做了:

命令.java:

DateTimeFormatter dateTimeformatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 
List<RatingTiming> response = repo.findByserviceRequestedTimestampBetween(LocalDateTime.parse(query.getStartvalue(), dateTimeformatter), LocalDateTime.parse(query.getEndvalue(), dateTimeformatter));

Mogorepo.java:

public interface RatingResponseRepository extends MongoRepository<RatingTiming, String> {
    List<RatingTiming> findByserviceRequestedTimestampBetween(LocalDateTime startDate, LocalDateTime endDate);
}

json.java:

@JsonFormat
(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss'")
@JsonDeserialize(using = DateDeserializer.class)
@JsonProperty("serviceRequestedTimestamp")
public LocalDateTime serviceRequestedTimestamp;

标签: javadateparsing

解决方案


编辑问题后编辑:您收到的异常消息,Text '' could not be parsed at index 0表示您正在尝试将空字符串解析为日期时间,但由于字符串中应该有文本,因此失败。我无法从你分离的片段中看出空字符串是如何结束的。

java.time

恕我直言,您以错误的方式提出问题。只有在最简单的一次性程序中,您才应该将日期和时间从一种字符串格式转换为另一种格式。对于任何 Spring Boot 或其他严肃程序,您不应将日期和时间处理为字符串。您应该将它们解析为正确的日期时间对象,并且仅在需要提供字符串输出时才将它们格式化。

我建议您使用现代 Java 日期和时间 API java.time 进行日期和时间工作。要解析您的源字符串:

    DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendPattern(" (OOOO)")
            .toFormatter();
    
    String inputSource = "2020-04-14 00:00:00.0000000 (GMT-04:00)";
    
    OffsetDateTime dateTime = OffsetDateTime.parse(inputSource, inputFormatter);
    System.out.println(dateTime);

到目前为止的输出:

2020-04-14T00:00-04:00

它有点长。我们可以DateTimeFormatter直接从格式模式字符串创建一个。使用构建器的优点包括:

  • 我们正在重用两个内置格式化程序,而不是从头开始构建所有内容。
  • ISO_LOCAL_TIME在秒上接受可变数量的小数,因此我们得到了一个更灵活的格式化程序。

为了格式化输出的日期和时间,我假设 (1) 您确实想要 ISO 8601 格式输出,因为您的示例字符串非常相似,并且 (2) 您想要相同的时间点。

    String formattedDateTime = dateTime.format(DateTimeFormatter.ISO_INSTANT);
    System.out.println(formattedDateTime);

2020-04-14T04:00:00Z

时间已更改为 04:00 UTC,Z您要求的尾随表示 UTC。这是正确的:当它是 4 AM UTC 时,它只是 00:00(午夜)在偏移量 GMT-04:00 的时区,源字符串来自哪里。您要求在秒上输入三位小数,但在 ISO 8601 中,小数为零时是可选的,因此此处不打印。如果您需要字符串与需要 ISO 8601 的系统进行数据交换,那么您已经准备就绪。

如果您想要相同的挂钟时间 00:00,即使它是不同的时区,您也可以拥有它:

    String formattedDateTime = dateTime.withOffsetSameLocal(ZoneOffset.UTC)
            .format(DateTimeFormatter.ISO_INSTANT);

2020-04-14T00:00:00Z

如果您真的想要您提到的确切格式,即使它不同意 ISO 8601,请使用自制格式化程序:

    DateTimeFormatter targetFormatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSX");
    String formattedDateTime = dateTime.withOffsetSameLocal(ZoneOffset.UTC)
            .format(targetFormatter);

2020-04-14 00:00:00.000Z

链接


推荐阅读