在 Java 中将字符串转换为 LocalDateTime
Convert String to LocalDateTime in Java
我有这个字符串
Fri, 07 Aug 2020 18:00:00 +0000
我需要将其转换为 LocalDateTime
我尝试了几种方法:
创建 DateTimeFormatter 并解析字符串
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss", Locale.getDefault());
LocalDateTime parsedDate = LocalDateTime.parse(publishedString, formatter);
使用 SimpleDateFormat 将其转换为 Date,然后将 resultDate 转换为 LocalDateTime
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
SimpleDateFormat dateFormatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z");
Date date = dateFormatter.parse(publishedString);
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
两种解决方案都给出了相同的异常:
java.time.format.DateTimeParseException: Text 'Fri, 07 Aug 2020 18:00:00 +0000' could not be parsed
at index 0 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
如何转换该字符串?
我会说使用 Locale.ROOT 并且不要忘记 DateTimeFormatter 中的 Z class
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss Z", Locale.ROOT);
LocalDateTime parsedDate = LocalDateTime.parse(dateString, formatter);
tl;博士
OffsetDateTime.parse(
"Fri, 07 Aug 2020 18:00:00 +0000" ,
DateTimeFormatter.RFC_1123_DATE_TIME
)
看到这个code run live at IdeOne.com。
LocalDateTime
是错误的class
您的输入字符串包含 +0000
,表示 offset-from-UTC。
所以你不应该使用 LocalDateTime
。 class 故意缺少任何时区或偏移量的概念。使用 LocalDateTime
,您的字符串 Fri, 07 Aug 2020 18:00:00 +0000
将在 2020 年 8 月 7 日变为 6M,但我们不知道那是日本东京下午 6 点、法国图卢兹下午 6 点还是美国俄亥俄州托莱多下午 6 点— 所有不同的时刻相隔几个小时。
OffsetDateTime
相反,此值应解析为 OffsetDateTime
。
正在解析
您输入的格式为 RFC 1123。该特定格式在 java.time.
中预定义
String input = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter f = DateTimeFormatter.RFC_1123_DATE_TIME;
OffsetDateTime odt = OffsetDateTime.parse( input , f );
odt.toString(): 2020-08-07T18:00Z
我知道您需要一个 LocalDateTime
用于 API,由于您无法控制的设计问题,您试图在某个时间点使用 LocalDateTime
。
如果外部合同规定要理解 LocalDateTime
在哪个时区或哪个 UTC 偏移,则 LocalDateTime
可以工作,至少在 99.977% 的情况下。当一些同事程序员没有阅读合同的那一天,你仍然会有一个编程错误等待发生,这是一个我们无法在代码中解决的问题,只能通过良好的评论来尝试缓解。
例如,如果合同上写的是 UTC,那么我们需要确保将时间转换为 UTC。为此,我们需要字符串的偏移量。
ZoneOffset contractualOffset = ZoneOffset.UTC;
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.withOffsetSameInstant(contractualOffset)
.toLocalDateTime();
System.out.println(convertedDateTime);
输出:
2020-08-07T18:00
如果字符串中的偏移量已经被要求为 0,则您需要验证它是否为 0,否则错误将被忽视并且用户将得到错误的结果。例如:
OffsetDateTime parsedOdt = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME);
if (! parsedOdt.getOffset().equals(contractualOffset)) {
throw new IllegalStateException("Offset must be " + contractualOffset
+ ", was " + parsedOdt.getOffset());
}
LocalDateTime convertedDateTime = parsedOdt.toLocalDateTime();
如果合同提及某个时区,则转换为该时区。我以Australia/Victoria为例。
ZoneId contractualZone = ZoneId.of("Australia/Victoria");
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.atZoneSameInstant(contractualZone)
.toLocalDateTime();
System.out.println(convertedDateTime);
2020-08-08T04:00
在时钟向后转动的时间异常情况下,例如在夏令时 (DST) 结束时后退,您会得到不明确的结果。
你的代码出了什么问题?
这里解释了你的异常原因:
- java DateTimeFormatterBuilder fails on testtime
我有这个字符串
Fri, 07 Aug 2020 18:00:00 +0000
我需要将其转换为 LocalDateTime
我尝试了几种方法:
创建 DateTimeFormatter 并解析字符串
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss", Locale.getDefault());
LocalDateTime parsedDate = LocalDateTime.parse(publishedString, formatter);
使用 SimpleDateFormat 将其转换为 Date,然后将 resultDate 转换为 LocalDateTime
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
SimpleDateFormat dateFormatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z");
Date date = dateFormatter.parse(publishedString);
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
两种解决方案都给出了相同的异常:
java.time.format.DateTimeParseException: Text 'Fri, 07 Aug 2020 18:00:00 +0000' could not be parsed
at index 0 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
如何转换该字符串?
我会说使用 Locale.ROOT 并且不要忘记 DateTimeFormatter 中的 Z class
String dateString = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, dd MMM yyyy HH:mm:ss Z", Locale.ROOT);
LocalDateTime parsedDate = LocalDateTime.parse(dateString, formatter);
tl;博士
OffsetDateTime.parse(
"Fri, 07 Aug 2020 18:00:00 +0000" ,
DateTimeFormatter.RFC_1123_DATE_TIME
)
看到这个code run live at IdeOne.com。
LocalDateTime
是错误的class
您的输入字符串包含 +0000
,表示 offset-from-UTC。
所以你不应该使用 LocalDateTime
。 class 故意缺少任何时区或偏移量的概念。使用 LocalDateTime
,您的字符串 Fri, 07 Aug 2020 18:00:00 +0000
将在 2020 年 8 月 7 日变为 6M,但我们不知道那是日本东京下午 6 点、法国图卢兹下午 6 点还是美国俄亥俄州托莱多下午 6 点— 所有不同的时刻相隔几个小时。
OffsetDateTime
相反,此值应解析为 OffsetDateTime
。
正在解析
您输入的格式为 RFC 1123。该特定格式在 java.time.
中预定义String input = "Fri, 07 Aug 2020 18:00:00 +0000";
DateTimeFormatter f = DateTimeFormatter.RFC_1123_DATE_TIME;
OffsetDateTime odt = OffsetDateTime.parse( input , f );
odt.toString(): 2020-08-07T18:00Z
我知道您需要一个 LocalDateTime
用于 API,由于您无法控制的设计问题,您试图在某个时间点使用 LocalDateTime
。
如果外部合同规定要理解 LocalDateTime
在哪个时区或哪个 UTC 偏移,则 LocalDateTime
可以工作,至少在 99.977% 的情况下。当一些同事程序员没有阅读合同的那一天,你仍然会有一个编程错误等待发生,这是一个我们无法在代码中解决的问题,只能通过良好的评论来尝试缓解。
例如,如果合同上写的是 UTC,那么我们需要确保将时间转换为 UTC。为此,我们需要字符串的偏移量。
ZoneOffset contractualOffset = ZoneOffset.UTC;
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.withOffsetSameInstant(contractualOffset)
.toLocalDateTime();
System.out.println(convertedDateTime);
输出:
2020-08-07T18:00
如果字符串中的偏移量已经被要求为 0,则您需要验证它是否为 0,否则错误将被忽视并且用户将得到错误的结果。例如:
OffsetDateTime parsedOdt = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME);
if (! parsedOdt.getOffset().equals(contractualOffset)) {
throw new IllegalStateException("Offset must be " + contractualOffset
+ ", was " + parsedOdt.getOffset());
}
LocalDateTime convertedDateTime = parsedOdt.toLocalDateTime();
如果合同提及某个时区,则转换为该时区。我以Australia/Victoria为例。
ZoneId contractualZone = ZoneId.of("Australia/Victoria");
String stringWeveGot = "Fri, 07 Aug 2020 18:00:00 +0000";
LocalDateTime convertedDateTime = OffsetDateTime
.parse(stringWeveGot, DateTimeFormatter.RFC_1123_DATE_TIME)
.atZoneSameInstant(contractualZone)
.toLocalDateTime();
System.out.println(convertedDateTime);
2020-08-08T04:00
在时钟向后转动的时间异常情况下,例如在夏令时 (DST) 结束时后退,您会得到不明确的结果。
你的代码出了什么问题?
这里解释了你的异常原因:
- java DateTimeFormatterBuilder fails on testtime