我收到ParseException
以获取以下代码
String dateStr = "2011-12-22 10:56:24.389362";
String formatStr = "yyyy-MM-dd HH:mm:ss.SSSSSS";
Date testDate = null;
SimpleDateFormat sdf= new SimpleDateFormat(formatStr);
sdf.setLenient(false);
testDate = sdf.parse(dateStr);
System.out.println("CHECK DATE " + sdf.format(testDate));
Exception in thread "main" java.text.ParseException: Unparseable date: "2011-12-22 10:56:24.389362"
at java.text.DateFormat.parse(DateFormat.java:337)
如果我注释掉sdf.setLenient(false)
行,那么我会看到输出的时差
CHECK DATE 2011-12-22 11:02:53.000362
我做错了什么?
答案 0 :(得分:7)
'S'是毫秒。一秒钟内有1000(0到999)毫秒。 389362大于999.额外的389000毫秒转换为389秒,或6分29秒,并添加到时间。
答案 1 :(得分:4)
S
格式说明符是指毫秒。当您允许宽松解析时,最后一部分被解释为389362毫秒。当这个被添加到目前为止的日期时,最后3个数字(实际上,值为%1000)变为实际的毫秒数,并且你的日期约为389秒(~6 1/2分钟),比您预期的要晚。 (通过严格的解析,解析器知道389362毫秒没有意义,因此它会抛出错误。)
最简单的方法是,如果你可以保证日期总是这样,那就是砍掉最后3位数。 (这大约有一半的时间会让你的日期偏离一毫秒。但这比编写日期解析器更好......)
答案 2 :(得分:3)
您输入的日期毫秒数不正确。它应该是: -
String dateStr = "2011-12-22 10:56:24.389";
您也不需要模式中额外数量的“S”。以下就足够了:
String formatStr = "yyyy-MM-dd HH:mm:ss.S";
在java docs中明确提到Number
的演示文稿类型:
数字:对于格式化,模式字母的数量是最小的 数字和较短的数字被零填充到此数量。 对于解析,忽略模式字母的数量,除非它是 需要将两个相邻的区域分开。
当你将lenient设置为true(或注释掉默认为true的行)时它会起作用,因为你要求解析器对解析不严格。来自setLenient()上的java文档: -
指定日期/时间解析是否宽松。同 宽松解析,解析器可以使用启发式来解释输入 与该对象的格式不完全匹配。通过严格的解析, 输入必须与此对象的格式匹配。
答案 3 :(得分:2)
S
仅用于milliseconds。如果你想要微秒,你必须编写自己的解析器。
答案 4 :(得分:0)
使用toISOString('HH:mm:ss.S')
获取毫秒(3位数),然后根据需要使用0完成。
例如:
new Date().toISOString('HH:mm:ss.S')
返回“2012-02-10T12:16:39.124Z”