8

我一直在调试一些现有代码,这些代码在我的系统上单元测试失败,但在同事的系统上没有。根本原因是 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)是该测试模仿的生产代码中使用的内容,因此我不想更改它。

4

3 回答 3

6

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

IBM 的 J9 JVM 似乎在 DateFormat 的解析例程中存在一些错误和不兼容性,SimpleDateFormat 很可能继承了它,因为它是 DateFormat 的子类。一些证据支持 IBM 的 J9 的运行方式与您可能期望的其他 JVM(如 Sun 的 HotSpot JVM)的运行方式不同,请参见此处

请注意,这些错误和不兼容性在 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 的早期版本。有时错误确实会蔓延到各个版本中,并且会在以后的版本中得到修复。您能否修改您的问题以包含您系统的“java -version”信息?

无论哪种方式,这两者都只是有根据的猜测。代码应该按照编写的方式工作。

于 2010-06-03T16:06:53.237 回答
1

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

这篇文章显示了一个类似的问题,并说它应该在 v6 上修复。

您可以在此处找到多个版本的更改列表。

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

于 2010-06-03T16:31:51.327 回答
0

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

日期是根据语言环境解析的,因此只有当您的 LANG 设置为英语时,“Jul”才作为 7 月起作用,否则会引发 ParseException。

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

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

于 2011-08-04T14:17:00.363 回答