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