2020-12-16T16:27:57+00:00 的 DateFormat ParseException

时间:2020-12-23 08:21:31

标签: java date datetime simpledateformat java-time

        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 来自 https://help.sumologic.com/03Send-Data/Sources/04Reference-Information-for-Sources/Timestamps%2C-Time-Zones%2C-Time-Ranges%2C-and-Date-Formats

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

我也试过

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

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

3 个答案:

答案 0 :(得分: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-Timemaintenance mode 项目建议迁移到 java.time 类。

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

从哪里获取 java.time 类?

答案 1 :(得分:1)

想通了

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

答案 2 :(得分:0)

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. 尽管此解析不是强制性的,但您不应在没有 SimpleDateFormat 的情况下使用 DateTimeFormatterLocale。检查 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 并从中获取格式化的字符串。