为什么在使用SimpleDateFormat格式化日期然后解析它时会出现ParseException? [英] Why am I getting a ParseException when using SimpleDateFormat to format a date and then parse it?

查看:187
本文介绍了为什么在使用SimpleDateFormat格式化日期然后解析它时会出现ParseException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在调试一些现有的代码,我的系统上的单元测试失败,但同事的系统没有。根本原因是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;

公共类FormatsTest扩展TestCase {

public void testParse()抛出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)
在FormatsTest.testParse(FormatsTest.java:16)

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

解决方案

---在响应后编辑,表明开发人员正在使用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绑定的人倾向于解决这个问题。 JVM不使用DateFormat.parse(...)(或SimpleDateFormat.parse(...))。相反,他们倾向于使用java.util.regex.Matcher手动解析字段。



也许J9 JVM的更高版本修复了这个问题,也许不是。 / p>

---原帖如下---



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

  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信息吗?



无论哪种方式,这两种方法都只是有根据的猜测。代码应该按照书面形式工作。


I have been debugging some existing code for which unit tests are failing on my system, but not on colleagues' systems. The root cause is that SimpleDateFormat is throwing ParseExceptions when parsing dates that should be parseable. I created a unit test that demonstrates the code that is failing on my system:

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()));
    }
}

This test throws a ParseException on my system, but runs successfully on other systems.

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

I have found that I can setLenient(true) and the test will succeed. The setLenient(false) is what is used in the production code that this test mimics, so I don't want to change it.

解决方案

--- Edited after response indicating that the developer is using IBM's J9 1.5.0 Java Virtual Machine ---

IBM's J9 JVM seems to have a few bugs and incompatibilities in the parse routine of DateFormat, which SimpleDateFormat likely inherits because it is a subclass of DateFormat. Some evidence to support that IBM's J9 isn't functioning quite the way you might expect other JVMs (like Sun's HotSpot JVM) can be seen here.

Note that these bugs and incompatibilites are not even consistent within the J9 JVM, in other words, the IBM J9 formatting logic might actually generate formatted times that are not compatible with the IBM J9 parsing logic.

It seems that people who are tied to IBM's J9 JVM tend to work around the bug in the JVM by not using DateFormat.parse(...) (or SimpleDateFormat.parse(...)). Instead they tend to use java.util.regex.Matcher to parse the fields out manually.

Perhaps a later release of the J9 JVM fixes the issue, perhaps not.

--- Original post follows ---

Funny, the same code modified to:

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();
 }

}

runs fine on my system. I would wager that it is something in your environment. Either you are compiling the code on one JVM major release and running it on another (which can cause some issues as the libraries could be out of date) or the system you are running it on might be reporting the time zone information oddly.

Finally, you might want to consider if you are using a very early point release of the JVM. Sometimes bugs do creep into the various versions, and they are fixed in later point releases. Could you please modify your question to include the "java -version" information for you system?

Either way, both of these are just educated guesses. The code should work as written.

这篇关于为什么在使用SimpleDateFormat格式化日期然后解析它时会出现ParseException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆