代码之家  ›  专栏  ›  技术社区  ›  Greg

当使用simpledateformat格式化一个日期然后解析它时,为什么会得到一个parseException?

  •  8
  • Greg  · 技术社区  · 16 年前

    我一直在调试一些现有的代码,这些代码的单元测试在我的系统上失败了,但在同事的系统上失败了。根本原因是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 回复  |  直到 11 年前
        1
  •  6
  •   Edwin Buck    16 年前

    -编辑后响应表明开发者正在使用IBM的J91.5.0 Java虚拟机---

    IBM的J9JVM在dateformat的解析例程中似乎有一些bug和不兼容性,simpledateformat可能继承这些bug和不兼容性,因为它是dateformat的子类。可以看到一些支持IBM的J9运行方式与您预期的其他JVM(如Sun的Hotspot JVM)运行方式不同的证据。 here .

    请注意,这些bug和不兼容甚至在J9JVM中都不一致,换句话说,IBMJ9格式化逻辑实际上可能会生成与IBMJ9解析逻辑不兼容的格式化时间。

    似乎与IBM的J9JVM有联系的人倾向于不使用dateformat.parse(…)(或simpledateformat.parse(…)来解决JVM中的错误。相反,他们倾向于使用java.util.regex.matcher手动解析字段。

    也许J9JVM的稍后版本会解决这个问题,也许不会。

    ——原岗位如下---

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

    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版本”信息为您的系统?

    不管怎样,这两种猜测都是有根据的。代码应该按书面形式工作。

        2
  •  1
  •   OscarRyz    16 年前

    这可能是IBM的J9VM中关于simpledateformat类的一个bug。

    This post 显示一个类似的问题,并说它应该在V6上修复。

    您可以找到几个版本的更改列表 here .

    我看到有一个与日期格式有关的数字。所以,您可能应该向IBM提交一个bug报告或其他东西,让他们给您一个补丁。

        3
  •  0
  •   David Riccitelli    15 年前

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

    日期是根据区域设置进行分析的,因此只有当您的语言设置为English时,“jul”才作为july工作,否则将引发ParseException。

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

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