【问题标题】:DateFormat ParseException for 2020-12-16T16:27:57+00:002020-12-16T16:27:57+00:00 的 DateFormat ParseException
【发布时间】:2020-12-23 08:21:31
【问题描述】:
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss`ZZ:ZZ`");
        sdf.parse("2020-12-16T16:27:57+00:00");

我不确定日期的格式,但我很确定它是 yyyy-MM-dd'T'HH:mm:ssZZ:ZZ 或类似的东西。我在猜测 z's from https://help.sumologic.com/03Send-Data/Sources/04Reference-Information-for-Sources/Timestamps%2C-Time-Zones%2C-Time-Ranges%2C-and-Date-Formats

什么是正确的格式以及如何将其转换为 ms?

我也试过

Instant instant = Instant.parse("2020-12-16T16:27:57+00:00");

我从我的世界 json 文件中获取它。我拒绝使用 joda time,因为 minecraft 最初是用 java 5 编写的,并且没有使用 joda time 来做。他们后来更新到 java 7

【问题讨论】:

  • 标题中的示例中似乎没有那些单引号。
  • 好的,但是,你能告诉我日期的格式吗?我正在查看一个没有相关文档的 web json api。除了这个
  • (1) 我建议你不要使用SimpleDateFormatDate。这些类设计不佳且早已过时,尤其是前者,尤其是出了名的麻烦。而是使用来自java.time, the modern Java date and time APIOffsetDateTime。 (2) 格式为国际标准 ISO 8601。

标签: java date datetime simpledateformat java-time


【解决方案1】:
OffsetDateTime.parse( "2020-12-16T16:27:57+00:00" )

永远不要使用 SimpleDateFormat 或其他在几年前被现代 java.time 类取代的糟糕的日期时间类。

java.time 类在解析/生成表示日期时间值的字符串时默认使用标准ISO 8601 格式。您的输入是其中一种标准格式。所以不需要指定格式模式。


关于java.time

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

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

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

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 & JPA 2.2 支持 java.time

从哪里获取 java.time 类?

【讨论】:

    【解决方案2】:

    想通了

         * parse them zula times. example: 2010-09-18T21:35:15.000Z
         */
        public static long parseZTime(String strTime) 
        {
            return Instant.parse(strTime).toEpochMilli();
        }
        
        /**
         * parse the offset times. example: 2015-11-10T16:43:29-0500 and 2014-05-14T17:29:23+00:00
         */
        public static long parseOffsetTime(String strTime)
        {
            return OffsetDateTime.parse(strTime).toInstant().toEpochMilli();
        }
    

    【讨论】:

    • 感谢您发布您的解决方案 (+1)。你的parseOffsetTime() 也接受2010-09-18T21:35:15.000Z,所以你不一定需要两个方法。
    【解决方案3】:

    java.time

    java.util 的日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,转用modern date-time API

    使用现代日期时间 API:

    由于您的日期时间字符串符合ISO-8601 格式,您可以直接(即不使用DateTimeFormatter)将其解析为OffsetDateTime

    import java.time.OffsetDateTime;
    import java.util.concurrent.TimeUnit;
    
    public class Main {
        public static void main(String[] args) {
            String strDateTime = "2020-12-16T16:27:57+00:00";
            OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
            System.out.println(odt);
            System.out.println("No of milliseconds from Epoch: " + odt.toInstant().toEpochMilli());
            // Alternatively
            System.out.println("No of milliseconds from Epoch: " + TimeUnit.SECONDS.toMillis(odt.toEpochSecond()));
        }
    }
    

    输出:

    2020-12-16T16:27:57Z
    No of milliseconds from Epoch: 1608136077000
    No of milliseconds from Epoch: 1608136077000
    

    你的回答出了什么问题?

    1. 使用ZZ:ZZ 而不是单个X查看documentation 了解更多信息。另外,我不确定您是否将ZZ:ZZ 括在引号内,用于格式化代码,只是为了将其突出显示为代码,或者您确实在实际代码中这样做了。确保不要将Z 括在单引号内;否则,它将仅表示 Z 作为字符文字而不是时区。检查this answer 以更好地理解它。
    2. 尽管此解析不是强制性的,但您绝不应在没有Locale 的情况下使用SimpleDateFormatDateTimeFormatter。检查this answer 以更好地理解它。

    使用旧版 API:

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.time.Instant;
    import java.util.Date;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) throws ParseException {
            String strDateTime = "2020-12-16T16:27:57+00:00";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX", Locale.ENGLISH);
            Date date = sdf.parse(strDateTime);
            System.out.println(date);
            System.out.println("No of milliseconds from Epoch: " + date.getTime());
    
            // Given below is how you can convert the legacy type, java.util.Date to the
            // modern type java.time.Instant
            Instant instant = date.toInstant();
            System.out.println("No of milliseconds from Epoch: " + instant.toEpochMilli());
        }
    }
    

    输出:

    Wed Dec 16 16:27:57 GMT 2020
    No of milliseconds from Epoch: 1608136077000
    No of milliseconds from Epoch: 1608136077000
    

    注意java.util.Date 对象不是像modern date-time types 那样的真实日期时间对象;相反,它表示自称为“纪元”的标准基准时间以来的毫秒数,即January 1, 1970, 00:00:00 GMT(或 UTC)。当您打印java.util.Date 的对象时,它的toString 方法会返回JVM 时区中的日期时间,从这个毫秒值计算得出。如果您需要在不同的时区打印日期时间,则需要将时区设置为SimpleDateFormat 并从中获取格式化字符串。

    【讨论】:

      猜你喜欢
      • 2021-03-30
      • 2021-07-10
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-10
      • 2020-09-04
      相关资源
      最近更新 更多