在Java中解析日期时出现异常

4

根据评论修改后

不知道为什么,我在尝试在Java中解析DateString格式时,好像随机地会出现这个异常。

以下是我测试用的代码片段:

SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
for(...){
  ...
   System.out.println("Before parsing: [" + lastEntryDate + "]");
   Date date = formatter.parse(lastEntryDate);
   System.out.println("After parsing: [" + date + "]”);
}

输出结果如下:

Before parsing: [Sun Aug 07 22:45:30 EST 2011]
After parsing: [Sun Aug 07 22:45:30 EST 2011]
Before parsing: [Sun Aug 07 22:45:31 EST 2011]
After parsing: [Sun Aug 07 22:45:31 EST 2011]
Before parsing: [Sun Aug 07 22:45:31 EST 2011]
After parsing: [Sun Aug 07 22:45:31 EST 2011]
Before parsing: [Sun Aug 07 22:45:31 EST 2011]
After parsing: [Sun Aug 07 22:45:31 EST 2011]
Before parsing: [Sun Aug 07 22:45:31 EST 2011]
After parsing: [Sun Aug 07 22:45:31 EST 2011]
Before parsing: [Sun Aug 07 22:45:31 EST 2011]
java.lang.NumberFormatException: For input string: ""
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Long.parseLong(Long.java:431)
    at java.lang.Long.parseLong(Long.java:468)
    at java.text.DigitList.getLong(DigitList.java:177)
    at java.text.DecimalFormat.parse(DecimalFormat.java:1298)
    at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1936)
    at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1312)
    at java.text.DateFormat.parse(DateFormat.java:335)
    at proj01.servicebus.ServiceBus.writeFeedEntry(ServiceBus.java:211)
    at proj01.servicebus.ServiceBus.writeFeedEntries(ServiceBus.java:243)
    at proj01.servicebus.ServiceBus.access$1(ServiceBus.java:241)
    at proj01.servicebus.ServiceBus$1.call(ServiceBus.java:84)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)

问题是:
  • 有时候解析失败了?!(例如,它会给出00:00:00)
  • 有时候会抛出异常?!
  • 这个问题似乎是随机的!
可能的原因和解决方案是什么?
4个回答

8

看起来你正在尝试解析一个空字符串。因此,错误在输入数据中 - 不幸的是,在这种情况下,由于只调用了一次System.out.println,所以你不会显示坏数据的内容,而是在解析之后。

如果你将诊断信息更改为:

System.out.println("Before parsing: [" + lastEntryDate + "]");
Date date = formatter.parse(lastEntryDate);
System.out.println("After parsing: [" + date + "]");

我猜你会发现,当数据缺失或完全无效时,会出现异常;当它解析为"Sun Aug 07 00:00:00 EST 2011" 时,我猜你会发现输入数据确实有这些信息。

编辑:如果你使用多个线程,你不应该在线程之间共享SimpleDateFormat。要么在每个线程中创建一个,要么(我更喜欢的方法)使用 Joda Time - 它是一款更好的库,并且其格式化程序线程安全的。


好的,我根据你的建议编辑了原帖...但似乎仍然不清楚错误出在哪里?! - Larry
@Larry:这表明问题出现在你展示给我们的任何代码之前。writeFeedEntry的第211行是什么样子的? - Jon Skeet
第211行指向formatter.parse()方法...但我认为问题可能是Stephen建议的,因为我的代码确实涉及多个线程。 - Larry
是的,我正在全局静态声明 SimpleDateFormat formatter,然后为每个线程使用它... - Larry
1
@M Platvoet:我的回答没有错误——它只是不是问题的原因。我认为这两种情况之间有很大的区别。这不像是我在给出错误的建议——只是根据提供的代码,没有理由认为线程会参与进来。Stephen的猜测是一个非常好的猜测,但我不认为这意味着完全合理的建议应该被点踩。 - Jon Skeet
显示剩余5条评论

8
一种在相同输入条件下“随机”出现的故障很有可能是线程问题。根据堆栈跟踪信息,我认为您在该测试中最有可能使用了多个线程。
我怀疑问题出在您没有正确同步使用一个SimpleDateFormat对象,而是在多个线程之间共享它。javadoc关于SimpleDateFormat的说明如下:

"日期格式不是同步的。建议为每个线程创建单独的格式实例。如果多个线程同时访问一个格式,则必须在外部进行同步。".


没错,我确实有多个线程访问同一个格式化程序,让我尝试修改一下看会发生什么... - Larry

0

你介意分两次输出内容吗?这样即使解析失败,我们也能始终看到你试图解析的内容:

System.out.print("["+lastEntryDate );
System.out.println("||"+formatter.parse(lastEntryDate)+"]”);`

实际上,我们无法看到导致解析失败的输入数据。


0
值得一提的是,自Java 8以来,引入了一个新的DateTimeFormatter类。
The new DateTimeFormatter class is immutable and thread-safe. 

如果我们使用的是Java 8或更高版本,建议使用新的DateTimeFormatter类。


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