使用 java.time 将日期从“06/25/2021 10:26:33.0”格式解析为“2021-06-25T10:26:33.000-04:00”

parsing date from "06/25/2021 10:26:33.0" format to "2021-06-25T10:26:33.000-04:00" using java.time

为了使用 junit 进行比较,我必须转换日期。我从数据库中得到一个日期“06/25/2021 10:26:33.0”,我必须将其转换为“2021-06-25T 10:26:33.000-04:00" 在断言中使用它之前。

我尽量不在 java 中使用 SimpleDate,而是使用内置的 java.time。但是,我认为我并没有真正理解其中的所有内容。这是我一直在玩的代码片段。我已经用这个尝试了很多东西,当解析发生时我总是得到一个错误。

 public String test() throws ParseException {
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
    LocalDateTime ldt = LocalDateTime.parse("06/25/2021 10:26:33.0", dtf);
    //After the above line I have a date like: 2021-06-25T10:26:33.0
    ZoneId zone = ZoneId.of("UTC-04:00");
    ZonedDateTime zdt = ldt.atZone(zone);
    Instant instant = zdt.toInstant();
    return instant.toString();
}

在我看来,我认为我必须首先将日期转换为“可接受的”格式,因为我觉得字符串的这种格式 - “yyyy-MM-dd HH:mm:ss.S”不是java.time 可以处理的事情。它给了我一个错误,例如“Text could not be parsed at index 19”,然后可能在第二遍中将其转换为这个“2021-06-25T10:26:33” .000-04:00".

我在 SO 上查阅了几篇关于此的文章,但未能找到有助于转换自定义格式的内容。我知道“解析”和“格式”是必须在此处利用的 2 API 方法,但不确定如何去做。有人可以在正确的方向推动我吗?

您可以使用 LocalDateTime#atOffset 来满足此要求。

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String input = "06/25/2021 10:26:33.0";
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("M/d/u H:m:s.S", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse(input, dtfInput);
        OffsetDateTime odt = ldt.atOffset(ZoneOffset.of("-04:00"));
        System.out.println(odt);

        // Formatted output
        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
        String formatted = dtfOutput.format(odt);
        System.out.println(formatted);
    }
}

输出:

2021-06-25T10:26:33-04:00
2021-06-25T10:26:33.000-04:00

ONLINE DEMO

备注:

  1. 如果输入中的秒小数可以是零到九位数字,请使用模式,M/d/u H:m:s[.[SSSSSSSSS][SSSSSSSS][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S]],其中已使用方括号指定了可选模式。
  2. OffsetDateTime#toString 省略秒和小数部分(如果它们为零)。使用 DateTimeFormatter 将它们放入格式化字符串中。

详细了解 modern Date-Time API* from Trail: Date Time


* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and

convert it to into this "2021-06-25T10:26:33.000-04:00".

我认为您需要一个自定义格式化程序。可能是以下内容:

    public String test() {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm:ss.S");
        LocalDateTime ldt = LocalDateTime.parse("06/25/2021 10:26:33.0", dtf);
        ZoneOffset zoff = ZoneOffset.ofHours(-4);
        OffsetDateTime ldt2 = ldt.atOffset(zoff);
        DateTimeFormatter tsf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxxx");
        return tsf.format(ldt2);
    }