SimpleDateFormat似乎在使用"yyyy-MM-dd HH:mm:ss.SSS0"格式时出现问题。

4
为什么下面的代码无法工作?看起来末尾的数字 0 是原因...
final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS0");
format.setLenient(false);

String d = format.format(new Date());
System.out.println(format.parse(d));

@cellige - 你能否请更新问题并提供一些数据集中的值。 - Saurabh
上面的代码为您格式化了一个值,但它无法解析回来。 - fields
毫秒只有3位数字,你的数据在数据库中是使用char/varchar还是date/datetime/timestamp值保存的?如果使用char/varchar,你可以修剪掉对数据没有任何价值的其他0值。 - Luiggi Mendoza
@LuiggiMendoza 是的,我可以这样做,当然我正在这样做,但是这个类中的 bug 不会让任何人感到奇怪吗?或者是我没有正确使用它吗? - fields
@Saurabh,我的错,有时候我表达不够清晰 :) - fields
显示剩余4条评论
1个回答

7

我不知道为什么需要在模式的末尾添加零(0),但是你应该将非模式字母用 '' 包含起来,以使它们有效:

final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS'0'");

更多信息:

你代码的问题在这一行。

System.out.println(format.parse(d));

尝试解析超过3位数毫秒的字符串到java.util.Date将导致异常。应使用以下模式来解析字符串:
"yyyy-MM-dd HH:mm:ss.SSS" //without the zero at the end, now your whole code will work...

如果您正在使用纳秒或您的数据包含纳秒,则可以忽略这些值,因为Java Date/Time API不支持纳秒(即使在文档中也没有提及)。
如果您真的非常需要纳秒用于各种目的,那么您应该使用字符串而不是日期对象。

更不用说文档上说引号是为了字母格式化器而设计的。它并没有说你需要使用它,而且从我的一些小测试来看,对于数字似乎没有什么影响。 - fields
你的日期值是什么样子的?为什么要解析带有额外零的日期? - Luiggi Mendoza
@RichardSitze 如果你是一位科学家,需要在任何操作中使用纳秒,那么你应该自己处理这些值,Java API 无法帮助你。不过,有一个 System.nanoTime() 方法可以将当前时间以纳秒形式存储在一个 long 变量中。你可以想出一个好的方法,将毫秒部分转换为 long,然后乘以 1000 并加上纳秒(需要很多努力...)。 - Luiggi Mendoza
@Luiggi,就解析毫秒而言,您的答案是正确的。但是,我认为正确的“答案”只是SimpleDateFormat.parse没有实现所描述的规范。我认为这是一个(轻微的)缺陷。您已经描述了限制,并提出了合理的解决方法-这很好。更糟糕的是,您建议使用引号也应该有效...但它并没有。 - Richard Sitze
@RichardSitze 我已经编辑了答案。问题不在格式上,而是在解析上,正如我在另一个部分中所解释的那样。 - Luiggi Mendoza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接