Java:日期解析,为什么会出现错误
前三行很好用。当我再次尝试将字符串解析为日期时,我得到一个错误。我怎样才能解决这个问题 错误如下所示:Java:日期解析,为什么会出现错误,java,date,simpledateformat,datetime-parsing,unparseable,Java,Date,Simpledateformat,Datetime Parsing,Unparseable,前三行很好用。当我再次尝试将字符串解析为日期时,我得到一个错误。我怎样才能解决这个问题 错误如下所示: Date date = new Date(); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SZ");//2018-02-05T18:00:51.001+0000 String text = dateFormat.format(date); Date test = da
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SZ");//2018-02-05T18:00:51.001+0000
String text = dateFormat.format(date);
Date test = dateFormat.parse(text);
我删除了与时区相关的简单日期格式中的Z,它给出了正确的输出,下面是代码片段
Caused by: java.text.ParseException: Unparseable date: "2018-02-07T15:32:13.214+0100"
at java.text.DateFormat.parse(DateFormat.java:366) ~[na:1.8.0_151]
at TimeRange.parseDateFromIsoString(TimeRange.java:33) ~[classes/:na]
我删除了与时区相关的简单日期格式中的Z,它给出了正确的输出,下面是代码片段
Caused by: java.text.ParseException: Unparseable date: "2018-02-07T15:32:13.214+0100"
at java.text.DateFormat.parse(DateFormat.java:366) ~[na:1.8.0_151]
at TimeRange.parseDateFromIsoString(TimeRange.java:33) ~[classes/:na]
为我工作。在模式的末尾使用“SSSZ”而不是“SZ”
为我工作。在模式的末尾用“SSSZ”代替“SZ”。我想给出一个现代的答案。因为我不鼓励使用
SimpleDateFormat
,所以稍后将详细介绍这一点
java.time
这将生成一个类似于2018-02-07T17:51:21.087+0100
的字符串,非常接近我认为您在问题中所追求的内容,并很好地解析了它。在格式模式字符串中使用SSS
时,它总是在几秒钟内产生3个小数,并且通过解析也需要正好3个小数。例如,您可以使用S
或SSSSSS
获取1或6位小数。在我的Java 9上,OffsetDateTime.now()
的精度为6位小数(微秒),因此如果我指定更少的值,我的格式将失去精度
编辑:为了向后兼容,您不能使用以下内容,但对于阅读本文的任何人,我希望提供一个没有显式格式化程序的变体:
OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.of("Europe/Rome"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxx");
String text = dateTime.format(formatter);
OffsetDateTime test = OffsetDateTime.parse(text, formatter);
生成的字符串中的两个差异是:
OffsetDateTime
对象的完整信息+01:00
SimpleDataFormat
类已经过时很久了,而且出了名的麻烦,所以即使您目前还没有遇到问题,我仍然建议您放弃它,改用现代java日期和时间APIjava.time
,就像我上面所做的那样
旧的SimpleDateFormat
和现代的DateTimeFormatter
之间的一个区别是,虽然现代格式化程序中的S
表示秒的分数,但在SimpleDateFormat
中,它表示毫秒,因此除3以外的任何数字都没有意义。然而,它接受其他数字。格式化时,格式化程序生成了足够毫秒的数字,例如,如果有21.089秒,则为89
,如果有13.214秒,则为214
。前者不正确,21.089秒呈现为21.89
。我坚信,当您只有一个S
时,三位数的毫秒会导致解析失败。在我的Java8和Java9上,它可以工作,还可以将21.89
解析为21秒89毫秒,这样就可以消除错误
这种行为与Java 9文档一致,该文档指出:“对于格式化,模式字母的数量是最小位数,较短的数字被零填充到此数量。对于解析,模式字母的数量被忽略,除非需要分隔两个相邻字段。”
链接
- 解释如何使用
java.time
- 我想提供一个现代的答案。因为我不鼓励使用
SimpleDateFormat
,所以稍后将详细介绍这一点
java.time
这将生成一个类似于2018-02-07T17:51:21.087+0100
的字符串,非常接近我认为您在问题中所追求的内容,并很好地解析了它。在格式模式字符串中使用SSS
时,它总是在几秒钟内产生3个小数,并且通过解析也需要正好3个小数。例如,您可以使用S
或SSSSSS
获取1或6位小数。在我的Java 9上,OffsetDateTime.now()
的精度为6位小数(微秒),因此如果我指定更少的值,我的格式将失去精度
编辑:为了向后兼容,您不能使用以下内容,但对于阅读本文的任何人,我希望提供一个没有显式格式化程序的变体:
OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.of("Europe/Rome"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxx");
String text = dateTime.format(formatter);
OffsetDateTime test = OffsetDateTime.parse(text, formatter);
生成的字符串中的两个差异是:
OffsetDateTime
对象的完整信息+01:00
SimpleDataFormat
类已经过时很久了,而且出了名的麻烦,所以即使您目前还没有遇到问题,我仍然建议您放弃它,改用现代java日期和时间APIjava.time
,就像我上面所做的那样
旧的SimpleDateFormat
和现代的DateTimeFormatter
之间的一个区别是,虽然现代格式化程序中的S
表示秒的分数,但在SimpleDateFormat
中,它表示毫秒,因此除3以外的任何数字都没有意义。然而,它接受其他数字。格式化时,格式化程序生成了足够毫秒的数字,例如,如果有21.089秒,则为89
,如果有13.214秒,则为214
。前者不正确,21.089秒呈现为21.89
。我坚信三位数的毫秒
String text = dateTime.toString();
OffsetDateTime test = OffsetDateTime.parse(text);