java - 如何解决java.text.ParseException:无法解析的日期:“Sat Sep 14 2019 00:00:00 GMT+0530(印度标准时间)”?
问题描述
我需要转换Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)
为日期。但我越来越
java.text.ParseException: Unparseable date: "Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)" exception
我试过了:
SimpleDateFormat formatter = new SimpleDateFormat("E MMM dd hh:mm:ss Z yyyy");
解决方案
java.time
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"EEE MMM dd uuuu HH:mm:ss 'GMT'xx (zzzz)", Locale.ENGLISH);
String str = "Sat Sep 14 2019 00:00:00 GMT+0530 (India Standard Time)";
TemporalAccessor parsed = formatter.parse(str);
ZonedDateTime zdt = ZonedDateTime.from(parsed);
// Check the offset against the time zone for validation
ZoneOffset offset = ZoneOffset.from(parsed);
if (offset.equals(zdt.getOffset())) {
System.out.println(zdt);
} else {
System.err.println("Offset doesn’t match");
}
此片段的输出是:
2019-09-14T00:00+05:30[亚洲/加尔各答]
不要使用SimpleDateFormat
和Date
。Thise 类设计不佳且早已过时。相反,我使用的是现代 Java 日期和时间 API java.time。与它一起工作要好得多。
验证为王。如果有一天您收到一个偏移量(如+0530
或)与时区(如或)-0400
不一致的字符串,您将需要发现并采取适当的措施。因此,我从解析的日期时间中取出偏移量,并将其与 Java 从时区派生的偏移量进行比较。在这种情况下,他们确实同意了。如果不是因为需要这种验证,解析 a 的正常方法会更简洁:India Standard Time
Australian Central Daylight Time
ZonedDateTime
ZonedDateTime zdt = ZonedDateTime.parse(str, formatter);
指定语言环境。 Sat
,Sep
并且India Standard Time
是英文的。如果您不确定使用英语语言环境进行解析,则解析很可能会失败。如果不是今天,那么有一天当您在具有不同区域设置的计算机上运行程序时。
你的代码出了什么问题?
您的格式模式字符串中有几个错误。虽然您收到的错误消息SimpleDateFormat
很笼统,但 java.time 有时更有帮助。让我们看看它是否可以帮助我们。使用您的格式模式字符串:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd hh:mm:ss Z yyyy", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(str, formatter);
这让我们
java.time.format.DateTimeParseException:无法在索引 13 处解析文本“2019 年 9 月 14 日星期六 00:00:00 GMT+0530(印度标准时间)”
索引 13 已经是东西了。字符串中的索引 13 是 in 所在的19
位置2019
。该parse
方法使用您的格式模式来解析字符串并成功解析Sat Sep 14 20
,因为它匹配E MMM dd hh
. 它知道一个小时只能是 2 位数字,因此只解析20
为 hour 和 then 对象,因为格式模式指定小时后有一个冒号,而 . 后面没有任何冒号20
。您现在可能已经看到,我们应该在格式模式中指定一年(uuuu
或yyyy
)之后。dd
让我们修复,移动yyyy
字符串:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss Z", Locale.ENGLISH);
java.time.format.DateTimeParseException:无法在索引 25 处解析文本“2019 年 9 月 14 日星期六 00:00:00 GMT+0530(印度标准时间)”
我们大约是两倍。索引 25 是在哪里GMT+0530
。所以这与格式模式 letter 不匹配Z
。文档说这Z
是针对区域偏移的,例如 +0000;-0800; -08:00。您的字符串GMT
在偏移量之前。我们通过将其转义为用单引号括起来的文字来解决它:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss 'GMT'Z", Locale.ENGLISH);
java.time.format.DateTimeParseException:无法解析文本“2019 年 9 月 14 日星期六 00:00:00 GMT+0530(印度标准时间)”,在索引 33 处找到未解析的文本
索引 33 是 之后的空格GMT+0530
。您的格式模式字符串到此结束。有一种方法可以指示解析器只解析尽可能多的字符串,但这会剥夺我们对时区的验证,所以我们不要诉诸于此。小写z
用于时区名称:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy hh:mm:ss 'GMT'Z (zzzz)", Locale.ENGLISH);
java.time.format.DateTimeParseException:无法解析文本“2019 年 9 月 14 日星期六 00:00:00 GMT+0530(印度标准时间)”:无法从 TemporalAccessor 获取 ZonedDateTime:{NanoOfSecond=0, MinuteOfHour=0, MilliOfSecond =0, MicroOfSecond=0, OffsetSeconds=19800, HourOfAmPm=0, SecondOfMinute=0},ISO,Asia/Kolkata 解析为 java.time.format.Parsed 类型的 2019-09-14
这是一个新的。需要注意的细节是HourOfAmPm=0
。我们不打算在字符串中的 AM 或 PM 中添加一个小时,只是一天中的一个小时。错误是小时的小写hh
。对于一天中从 00 到 23 的小时,我们需要大写HH
:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E MMM dd yyyy HH:mm:ss 'GMT'Z (zzzz)", Locale.ENGLISH);
现在解析成功并给出与上面相同的结果。我想说的是 java.time 正在努力帮助我们获得正确的格式模式。
链接
- Oracle 教程:日期时间解释如何使用 java.time。
DateTimeFormatter
带有格式模式字母规范的文档。
推荐阅读
- ffmpeg-php - PHP-ffmpeg ratecontrol_init:无法打开统计文件
- three.js - ThreeJS:如何使对象与背景颜色相同?
- reporting-services - SSRS:根据其他参数更新文本参数
- r - 在条件下删除零值的行
- php - 在 PHP Post 数组中插入复选框
- excel - Excel - 单元格匹配条件的返回值和包含匹配条件的行的最大值
- select - 如何使用 AS 关键字从转换后的日期列中查询
- swift - 从基于 macOS Swift 的应用程序中运行时,Apple 脚本失败
- unity3d - 有没有办法改变 Unity 的视图快捷方式?
- php - 为什么我的阵列不能插入到我的数据库中?