使用 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
备注:
- 如果输入中的秒小数可以是零到九位数字,请使用模式,
M/d/u H:m:s[.[SSSSSSSSS][SSSSSSSS][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S]]
,其中已使用方括号指定了可选模式。
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);
}
为了使用 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
备注:
- 如果输入中的秒小数可以是零到九位数字,请使用模式,
M/d/u H:m:s[.[SSSSSSSSS][SSSSSSSS][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S]]
,其中已使用方括号指定了可选模式。 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);
}