我在解析2013-01-09 09:15:03.000000格式的Java时间字符串时遇到问题。 在我的数据中,最后三个数字始终为0(表示输入字符串仅具有毫秒精度),因此我将此格式传递给SimpleDateFormat:
formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS'000'");
但是formatter.parse("2013-01-09 09:15:02.500000");引发异常:
Unparseable date:"2013-01-09 09:15:02.500000"
at java.text.DateFormat.parse(DateFormat.java:357)
有人知道如何正确执行吗? 我可以通过使用格式yyyy-MM-dd HH:mm:ss.SSS和使用substring摆脱最后三位数字来解决,但这确实很hacky。
编辑:谁能解释为什么格式字符串yyyy-MM-dd HH:mm:ss.SSS'000'不能用于解析时间"2013-01-09 09:15:02.500000"
我能看到的最大问题是解析器并不关心出现的位数(可以说),因此您可以.S并解析5,500或500000,但是 这将导致时间值的滚动以补偿...
@MadProgrammer,是否意味着如果我输入字符串"2013-01-09 09:15:02.5,它将解析为5毫秒而不是500毫秒? 那真是愚蠢。
也许是,但是它的作用是灵活的,因此您也可以通过2013-1-9 9:15:2.500使其生效。 解析的方式和格式化程序的方式稍有不同...
尝试java.sql.Timestamp
Timestamp ts = Timestamp.valueOf("2013-01-09 09:15:03.500000");
Date date = new Date(ts.getTime())
与SimpleDateFormat相比,它也是线程安全且快速的
我忘了提及,时间字符串实际上不是UTC时区,而是一些本地时区。 我希望能够设置时区并转换为UTC。 SimpleDateFormat可以设置时区,但不能设置时间戳。
时间戳解析本地时区的输入,请尝试String s = new SimpleDateFormat(" yyyy-MM-dd HH:mm:ss.SSS")。format(ts.getTime()); 你会得到相同的时间
格式也不灵活,只是说...
java.time
我想贡献现代的答案。使用java.time,现代的Java日期和时间API。一种选择是,您可以使用格式化程序:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS");
LocalDateTime dateTime = LocalDateTime.parse(timeString, formatter);
System.out.println(dateTime);
使用问题"2013-01-09 09:15:02.500000"中的字符串时,将输出:
2013-01-09T09:15:02.500
如果即使最后三位小数均为0,也要在秒上用六位小数来打印值,请使用相同的格式化程序将时间格式化为字符串:
System.out.println(dateTime.format(formatter));
另一种选择是,您可以利用以下事实:您的字符串类似于ISO 8601格式,现代类将其解析为默认格式,即没有任何显式格式化程序。只有ISO 8601带有T来表示时间部分的开始,但是我们可以轻松地解决该问题:
LocalDateTime dateTime = LocalDateTime.parse(timeString.replace(' ', 'T'));
它给出相同的结果,2013-01-09T09:15:02.500。它更短,但也更棘手。
何必呢?
类Date和Timestamp早已过时,特别是SimpleDateFormat已证明很麻烦。在您遇到的情况中,其令人惊讶的行为只是其中的一个小故事。通常,现代API更好用。
为什么格式化程序不起作用?
尽管SimpleDateFormat和DateTimeFormatter使用的格式模式字符串相似,但还是有所不同。一种是SimpleDateFormat将大写的S理解为毫秒,而不管它们是一还是九,而对于DateTimeFormatter而言,它们表示秒的分数。此外,您的SimpleDateFormat会抓住小数点后的所有六位数字,而忽略了您只键入了三个S的事实,因此没有零可与'000'匹配(顺便说一下,不需要撇号,只有字母需要它们)。
链接
Oracle教程
我想通了。仅供参考,Apache Commons的FastDateFormat似乎接受SSS000格式并正确解析时间。