为什么在使用SimpleDateFormat格式化日期然后解析它时会出现ParseException?

时间:2010-06-03 15:52:25

标签: java simpledateformat

我一直在调试一些现有的代码,这些代码的单元测试在我的系统上失败,但在同事的系统上没有。根本原因是SimpleDateFormat在解析应该可解析的日期时抛出ParseExceptions。我创建了一个单元测试,演示了我的系统失败的代码:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

import junit.framework.TestCase;

public class FormatsTest extends TestCase {

    public void testParse() throws ParseException {
        DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
        formatter.setTimeZone(TimeZone.getDefault());
        formatter.setLenient(false);

        formatter.parse(formatter.format(new Date()));
    }
}

此测试在我的系统上抛出ParseException,但在其他系统上成功运行。

java.text.ParseException: Unparseable date: "20100603100243.118 -0600"
    at java.text.DateFormat.parse(DateFormat.java:352)
    at FormatsTest.testParse(FormatsTest.java:16)

我发现我可以setLenient(true)并且测试会成功。 setLenient(false)是此测试模拟的生产代码中使用的内容,因此我不想更改它。

3 个答案:

答案 0 :(得分:6)

---在响应后编辑,表明开发人员正在使用IBM的J9 1.5.0 Java虚拟机---

IBM的J9 JVM似乎在DateFormat的解析例程中存在一些错误和不兼容性,SimpleDateFormat可能会继承它,因为它是DateFormat的子类。有些证据支持IBM的J9不能像你期望的那样运行其他JVM(如Sun的HotSpot JVM)here

请注意,这些错误和不兼容性在J9 JVM中甚至不一致,换句话说,IBM J9格式化逻辑实际上可能生成与IBM J9解析逻辑不兼容的格式化时间。

似乎与IBM的J9 JVM绑定的人倾向于通过不使用DateFormat.parse(...)(或SimpleDateFormat.parse(...))解决JVM中的错误。相反,他们倾向于使用java.util.regex.Matcher手动解析字段。

也许J9 JVM的后续版本修复了这个问题,也许不是。

---原帖如下---

有趣,相同的代码修改为:

import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.text.ParseException;

public class FormatsTest {

 public void testParse() throws ParseException {
  DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss.SSS Z");
  formatter.setTimeZone(TimeZone.getDefault());
  formatter.setLenient(false);
  System.out.println(formatter.format(new Date()));

  formatter.parse(formatter.format(new Date()));
 }

 public static void main(String[] args) throws Exception {
   FormatsTest test = new FormatsTest();
   test.testParse();
 }

}

在我的系统上正常运行。我敢打赌,这是你环境中的事情。您要么在一个JVM主要版本上编译代码并在另一个JVM主要版本上运行它(这可能会导致一些问题,因为库可能已过期),或者您运行它的系统可能会奇怪地报告时区信息。

最后,您可能想要考虑是否使用了JVM的早期版本。有时bug会进入各种版本,并且它们会在以后的版本中修复。你可以修改你的问题,为你的系统包含“java -version”信息吗?

无论哪种方式,这两者都只是受过教育的猜测。代码应该按照书面形式工作。

答案 1 :(得分:1)

这应该是IBM的J9 VM中关于SimpleDateFormat类的错误。

This post显示了类似的问题,并说它应该在第6版修复。

您可以找到多个版本here的更改列表。

我看到有一个与DateFormat相关的数字。因此,您可能应该向IBM提出错误报告或其他内容,以便为您提供补丁。

答案 2 :(得分:0)

检查计算机和远程计算机的LANG环境变量。

根据区域设置解析日期,因此只有当LANG设置为english时,'Jul'才能用作7月,否则会引发ParseException。

您可以通过运行export LANG="en_US.UTF-8"然后运行程序来进行快速测试。

您还可以使用以下方法以编程方式设置区域设置: DateFormat.getDateInstance(int, java.util.Locale)