我试图在Java 11中将字符串转换为Date对象,下面的代码给了我例外。尝试了不同的方法,到目前为止没有运气。对解决此错误消息有帮助吗?
String date = 'Mon Aug 02 16:33:10 EDT 2021'
OffsetDateTime odt = OffsetDateTime.now( ZoneId.systemDefault() ) ;
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy").toFormatter().ofLocalizedDateTime(FormatStyle.LONG) .withZone(odt.getOffset());
LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
System.out.println(localDateTime);
System.out.println(formatter.format(localDateTime));
错误
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Mon Aug 02 16:33:10 EDT 2021' could not be parsed at index 20
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)
at java_time_LocalDateTime$parse.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
答案 0 :(得分:1)
一个好的IDE会对您尝试编译的代码产生警告。例如,Eclipse警告
类型为
ofLocalizedDateTime(FormatStyle)
的静态方法DateTimeFormatter
应该以静态方式访问
Java允许您通过引用表达式访问类的static
个成员。不过,您已经should not达成强烈共识,只是忽略语言功能。
对于您的具体情况,
new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter()
.ofLocalizedDateTime(FormatStyle.LONG)
.withZone(odt.getOffset());
在类型为[...].toFormatter()
的引用表达式DateTimeFormatter
上调用静态DateTimeFormatter#ofLocalizedDate(FormatStyle)
。您似乎认为它是在实际的DateTimeFormatter
实例上调用的,但实际上只是一个static
方法的调用。 .toFormatter()
返回的实例将被丢弃。您的代码本质上等同于
new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter(); // thrown away
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withZone(odt.getOffset());
换句话说,您的formatter
具有ofLocalizedDateTime
选择的格式,而不是您尝试使用的"E MMM d H:m:s z yyyy"
。据推测,对于您的默认Locale
,该格式无法解析您的日期字符串。
目前尚不清楚您是否打算使用该方法。如果您知道具有适当格式的相应语言环境,则可以跳过自定义模式,而仅使用选择的模式
Locale currentLocale = /* whatever is appropriate */;
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withLocale(currentLocale);
,然后解析您的日期字符串。
否则,请完全忽略该方法,仅使用您提供的模式和时区来构建DateTimeFormatter
:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("E MMM d H:m:s z yyyy")
.toFormatter()
.withZone(odt.getOffset());
您可以从DateTimeFormatter
class javadoc得知您的模式字符串
E MMM d H:m:s z yyyy
可以适当地解析您的日期字符串
Mon Aug 02 16:33:10 EDT 2021
无关,您确定LocalDateTime
是您所需要的吗?您实际上会丢失原始字符串中的时区信息(EDT)。另外,提供给ZoneId
的{{1}}解析为withZone
时将被忽略。
答案 1 :(得分:0)
使用模式EEE MMM dd HH:mm:ss z yyyy
。
此外,由于您使用时区而不是日期时间字符串中的偏移量,因此应使用ZonedDateTime
而不是OffsetDateTime
。
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDate = "Mon Aug 02 16:33:10 EDT 2021";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy");
ZonedDateTime zdt = ZonedDateTime.parse(strDate, formatter);
System.out.println(zdt);
LocalDateTime ldt = zdt.toLocalDateTime();
System.out.println(ldt);
}
}
输出:
2021-08-02T16:33:10-04:00[America/New_York]
2021-08-02T16:33:10
注释(Courtesy Basil Bourque):从ZonedDateTime
转换为LocalDateTime
几乎毫无道理。这种转换会丢弃宝贵的信息(时区),而不会增加任何价值。
答案 2 :(得分:0)
在我的例子中,我解析的日期字符串的 am/pm 是小写的,就像这样
<块引用>2021 年 5 月 12 日下午 3:31
我必须先将 'pm' 转换为 'PM',然后使用格式化程序 DateTimeFormatter.ofPattern("MMMM d yyyy 'at' h:mm a");