【问题标题】:Convert String datetime to Date in java? [duplicate]在java中将字符串日期时间转换为日期? [复制]
【发布时间】:2016-03-08 08:57:16
【问题描述】:

我正在尝试将这两个字符串转换为日期,但出现异常无法解析的日期。

“2015-12-03T15:00:08.868987”和“2015-12-03T17:00:08Z”。尝试了这两种格式 “yyyy-MM-dd'T'HH:mm:ss.SSSXXX”和“yyyy-MM-dd'T'HH:mm:ss.SSSZ”

    String s = "2015-12-03T17:00:08Z";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    try
    {
        Date date = simpleDateFormat.parse(s);

        System.out.println("date : "+simpleDateFormat.format(date));
    }
    catch (ParseException ex)
    {
        System.out.println("Exception "+ex);
    }

【问题讨论】:

  • 您正在尝试使用需要毫秒和 RFC 822 时区的格式来解析没有毫秒和 ISO-8601 时区的日期。请参考Documentation
  • 有点题外话,但您可能想看看 Joda-Time,它消除了许多与核心 Java 日期/时间类相关的挫败感
  • @LawrenceTierney Joda-Time 库已被 Java 8 及更高版本中内置的新 java.time 框架所取代。有关 java.time 代码的讨论和示例,请参阅 my Answer。如果 Java 8 技术不可用,例如 Android,那么肯定推荐 Joda-Time 远优于与早期 Java 捆绑的旧日期时间类。
  • @BasilBourque 谢谢。我认为它已经改变然后说服自己否则#longDay

标签: java datetime


【解决方案1】:

原因是你使用了错误的格式,这里Z代表时区

 String s = "2013-09-29T18:46:19-0700";
 SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

如果时间格式在上面,它会正常工作。 如果你只是在单引号中标记 Z,它只会认为是一个字符串而不是解析它。

编辑:- 如果要使用“2015-12-03T15:00:08.8689870”,则模式必须为 yyyy-MM-dd'T'HH:mm:ss.SSS

String s = "2015-12-03T15:00:08.8689870";
SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");

如果日期时间在 2015-12-03T17:00:08Z,那么您可以使用模式 yyyy-MM-dd'T'HH:mm:ssX 其中 X 表示 ISO 8601 时区。Java 7 版本的 SimpleDateFormat支持使用大写字母 X 的 ISO-8601 时区。

String s = "2015-12-03T17:00:08Z";
SimpleDateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date dtIn = inFormat.parse(s); 

http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

如果您坚持使用 Java 6 或更早版本,推荐 JodaTime 的答案是安全的选择。

String timestamp = "2011-04-15T20:08:18Z";

DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime(timestamp);

这可以正确识别 UTC 时区,然后允许您使用 Joda Time 的广泛操作方法来获取您想要的内容。

【讨论】:

  • @RealSkeptic 这就是我在回答中解释的内容。这里的 Z 表示时区,如 GMT 等。所以要使用它,字符串必须采用正确的格式......
  • @RealSkeptic 它不是必需的 UTC,它可以是任何时区,PDT、UTC、GMT 等... String s = "2001.07.04 AD at 12:08:56 PDT"; SimpleDateFormat inFormat = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss Z");
  • @RealSkeptic 更新了答案...有两种方法可以实现...请参考答案
  • 如果问题解决,请将答案标记为“接受”。这样可以帮助其他人寻找类似问题。谢谢
【解决方案2】:
    String s = "2015/12/03/17:00:34";
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/HH:mm:ss");
    try
    {
        Date date = simpleDateFormat.parse(s);

        System.out.println("date : "+simpleDateFormat.format(date));
    }
    catch (ParseException ex)
    {
        System.out.println("Exception "+ex);
    }

修改你的字符串日期与 SimpleDateFormat 相同。

【讨论】:

    【解决方案3】:

    改变

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    

    【讨论】:

    • 否,因为 Z 在该日期字符串中有意义。在格式字符串中添加文字 'Z' 会忽略该含义(即日期为 UTC,而不是本地日期)。
    【解决方案4】:

    Pojava DateTime 库(在 Maven Central Repo 中)将解析两个日期,而无需指定格式。

    Date d1 = DateTime.parse("2015-12-03T15:00:08.868987").toDate();
    Date d2 = DateTime.parse("2015-12-03T17:00:08Z").toDate();
    System.out.println(d1); // Thu Dec 03 15:00:08 PST 2015
    System.out.println(d2); // Thu Dec 03 09:00:08 PST 2015
    

    【讨论】:

      【解决方案5】:

      数据丢失

      您正在解析带有六位小数秒的字符串输入,即microsecond

      您正在使用仅支持毫秒(3 位数)的旧 java.sql.Date 类。因此,即使您设法解析该输入,您也会丢失一些信息。

      java.time

      您正在使用的类java.util.Datejava.text.SimpleDateFormat 已被Java 8 及更高版本中内置的新java.time 框架所取代。

      新类的灵感来自非常成功的 Joda-Time 框架,旨在作为其继任者,在概念上相似但经过重新架构。由JSR 310 定义。由ThreeTen-Extra 项目扩展。见Tutorial

      java.time 类支持nanosecond 分辨率,最多9 位小数秒。因此,根据您的输入,不会丢失数据。

      ISO 8601

      您的两个字符串输入都采用ISO 8601 标准定义的格式。

      java.time 类在解析或生成日期时间值的字符串表示时默认使用 ISO 8601。所以我们可以指定一个预定义的格式化程序,而不是定义一个格式化程序模式。对于某些格式,我们甚至根本不需要指定格式化程序。

      示例代码

      你有两个输入字符串,所以两个例子。

      示例 1

      第一个字符串没有时区或从 UTC 偏移的信息。因此,我们必须指定一个时间来解释该输入的含义。我假设你的意图是UTC。我们通过调用withZone 将UTC 指定为时区。

      该时区也被指定为ZonedDateTime 对象的时区。也就是说,不会再进行时区调整。

      String input = "2015-12-03T15:00:08.868987";
      
      DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone ( ZoneOffset.UTC );
      ZonedDateTime zdt = ZonedDateTime.parse ( input , formatter );
      

      zdt: 2015-12-03T15:00:08.868987Z

      示例 2

      您的第二个字符串确实包含时区信息,格式为Z,代表Zulu,表示UTC

      java.time 框架提供Instant 类来表示UTC 时间轴上的时刻。您可以将ZonedDateTime 视为Instant 加上一个时区(ZoneId)。

      因为第二个字符串 (a) 是 UTC 时区,(b) 是 ISO 8601 格式,所以我们不需要指定任何格式化程序。 Instant类可以直接解析这样的String。

      String input = "2015-12-03T17:00:08Z";
      Instant instant = Instant.parse ( input );
      

      转储到控制台。

      System.out.println ( "instant: " + instant );
      

      即时:2015-12-03T17:00:08Z

      【讨论】:

        猜你喜欢
        • 2015-11-24
        • 2015-09-17
        • 2020-01-24
        • 1970-01-01
        • 1970-01-01
        • 2012-08-25
        • 2011-12-16
        • 2014-05-24
        • 1970-01-01
        相关资源
        最近更新 更多