【问题标题】:Inconsistent date parsing using SimpleDateFormat使用 SimpleDateFormat 的不一致日期解析
【发布时间】:2010-11-21 17:55:36
【问题描述】:

我真的在这个问题上摸不着头脑。我已经使用SimpleDateFormats 有一段时间没有遇到任何问题,但是现在,使用 SimpleDateFormat 解析日期(只是有时)完全是错误的。

具体来说:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = sdf.parse("2009-08-19 12:00:00");
System.out.print(date.toString());

打印字符串Wed Aug 19 00:00:00 EDT 2009。有没有搞错? - 它甚至不会一直解析到错误的日期!


更新:完美地修复了它。你不知道吗,这在其他一些地方也被滥用了。一定喜欢调试别人的代码:)

【问题讨论】:

  • 我希望人们在犯错时不要再称事物为“离奇”和“怪异”。 ://
  • 对不起。我正在调试我的前辈多年编写的代码,我希望能够信任。

标签: java date simpledateformat date-parsing


【解决方案1】:

tl;博士

LocalDateTime ldt = LocalDateTime.parse( "2009-08-19 12:00:00".replace( " " , "T" ) );

java.time

其他答案是正确的,但使用旧的日期时间类。那些麻烦的老类已经被 java.time 类取代了。

您的输入字符串接近标准ISO 8601 格式。通过用T 替换中间的空格来进行调整。然后可以在不指定格式模式的情况下对其进行解析。 java.time 类在解析/生成字符串时默认使用 ISO 8601。

String input = "2009-08-19 12:00:00".replace( " " , "T" );

输入数据没有关于offset-from-UTC 或时区的信息。所以我们解析为LocalDateTime

LocalDateTime ldt = LocalDateTime.parse( input );

如果根据上下文您知道预期的偏移量,请应用它。也许它是为UTC(零偏移)设计的,我们可以在其中使用常量ZoneOffset.UTC

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );

或者您可能知道它是针对特定时区的。时区是一个偏移量加上一组用于处理异常情况的规则,例如夏令时 (DST)。

ZonedDateTime zdt = ldt.atZone( ZoneId.of( "America/Montreal" ) );

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了旧的麻烦的日期时间类,例如java.util.Date.Calendarjava.text.SimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。

大部分 java.time 功能在ThreeTen-Backport 中向后移植到Java 6 和7,并进一步适应ThreeTenABP 中的Android(参见How to use…)。

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。

【讨论】:

    【解决方案2】:

    小时应指定为 HH 而不是 hh。查看http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html中有关日期和时间模式的部分

    【讨论】:

      【解决方案3】:

      您正在打印日期的 toString() 表示,而不是格式的表示。您可能还想检查小时表示。 H 和 h 的意思不同。 H 代表 24 小时制 (0-23),h 代表 12 小时制 (1-12),(还有 k 和 K 分别代表 1-24 和 0-11 的时间)

      您需要执行以下操作:

      //in reality obtain the date from elsewhere, e.g. new Date()
      Date date = sdf.parse("2009-08-19 12:00:00"); 
      
      //this format uses 12 hours for time
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
      //this format uses 24 hours for time
      SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      
      System.out.print(sdf.format(date));
      System.out.print(sdf2.format(date));
      

      【讨论】:

      • 我会尝试,但我认为它不会解决问题。在我的应用程序中,我实际上并没有转换回字符串。我正在将日期保存到数据库中,那里也有问题。
      • 您的格式字符串是否一致?一些 DBMS 会自动转换值,如果他们能弄清楚的话,有些则不会。列中的问题值是否在数据库级别应用了不同的格式?还是来自设置了不同参数的连接?
      【解决方案4】:

      我认为您想使用 HH 格式,而不是“hh”,以便您使用 00-23 之间的时间。 'hh' 采用以 12 小时为增量的格式,因此它假定它在 AM 中。

      所以这个

      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      Date date = sdf.parse("2009-08-19 12:00:00");
      System.out.print(date.toString());
      

      应该打印出来

      2009 年 8 月 19 日星期三 12:00:00 EDT

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-23
        • 2013-05-07
        • 2012-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多