【问题标题】:How to convert ISO8601 format into milliseconds?如何将 ISO8601 格式转换为毫秒?
【发布时间】:2014-12-18 15:15:30
【问题描述】:

考虑到 ISO8601 在 JSON 中的使用频率,我还没有找到一种真正简单的方法,这让我感到非常惊讶。

基本上,我会采用如下所示的字符串:2014-10-23T00:35:14.800Z 并将其转换为类似50 minutes ago 的字符串。

首先我要把2014-10-23T00:35:14.800Z改成2014-10-23'T'00:35:14.800Z,然后再转换成毫秒,就很简单了。

我当前的代码:

private void setTimestamp(String timeCreated) {
    int indexOfT = timeCreated.indexOf('T');

    String properFormat = new StringBuilder(timeCreated).insert(indexOfT + 1, "'")
                                                        .insert(indexOfT, "'")
                                                        .toString();

    timeStamp = (String) DateUtils.getRelativeTimeSpanString(Long.parseLong(properFormat),
                                  System.currentTimeMillis(), 
                                  DateUtils.SECONDS_IN_MILLIS);
}

罪魁祸首是Long.parseLong(properFormat)。我需要将properFormat 转换为毫秒。

【问题讨论】:

  • Joda Time
  • 如果您使用 Java 8,您可能会发现 this discussion 很有趣。
  • 请告诉我你为什么不赞成这个。
  • @David 我不是反对者。但我怀疑投票否决可能是由于 StackOverflow 上数百个问题和答案处理了这个主题。
  • @PM77-1 Android 中没有 Java 8 和 java.time。

标签: java android datetime


【解决方案1】:

tl;博士

Instant.parse( "2014-10-23T00:35:14.800Z" )
       .toEpochMilli()

java.time 中的单行器

java.time 框架内置于 Java 8 及更高版本中。这些新类取代了与 Java 的最早版本(如 java.util.Date/.Calendar)捆绑在一起的旧日期时间类。见Tutorial。 java.time 类也取代了非常成功的Joda-Time 库,由一些相同的人构建,包括由相同的Stephen Colbourne 领导。

InstantUTC 时间线上的一个时刻,分辨率为nanoseconds。您可以从其epochask it for a count of millisecondsUTC 中的 1970 年第一刻)。但请记住,Instant 可能有额外的数据,纳秒比毫秒更精细。因此,您可能会在几分之一秒内丢失数据

java.time 类在解析/生成字符串时使用标准 ISO 8601 格式。无需指定格式模式。 Instant 类可以directly parse 一个字符串。

Instant.parse( "2014-10-23T00:35:14.800Z" )

您可以通过调用 toEpochMilli 将其转换为自 1970 年第一刻 UTC 纪元以来的毫秒数

请注意可能的数据丢失,因为Instant 类可以保存纳秒。因此,提取毫秒将在任何小数秒内截断任何微秒或纳秒。您的示例字符串在小数秒中只有三位数字,因此只有毫秒。但是当转换为毫秒数时,六位或九位小数会被截断为三位。

long millisFromEpoch = Instant.parse( "2014-10-23T00:35:14.800Z" ).toEpochMilli();

要以小时-分钟-秒为单位获取经过的时间,请使用 Duration 类。及时为其between 方法提供一对时刻。

Duration duration = Duration.between( Instant.parse( "2014-10-23T00:35:14.800Z" ) , Instant.now() );

关于java.time

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

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

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

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

从哪里获得 java.time 类?


Joda-Time 单线

更新: Joda-Time 项目处于维护模式,团队建议迁移到 java.time 类。

使用Joda-Time 2.5 库:

long millisSinceEpoch = new DateTime( "2014-10-23T00:35:14.800Z" ).getMillis();

Joda-Time 默认解析并生成ISO 8601 字符串。 Joda-Time 适用于 Android。 java.util.Date/.Calendar 类是出了名的麻烦、混乱和缺陷。避开他们。

【讨论】:

  • 我想我肯定会用这个。似乎是为我的约会量身定做的单线。
  • 投反对票:请在投票的同时留下批评意见,尤其是在已接受的答案上。
  • Instant 仅在 API 26 后在 Android 上可用
  • @rightaway717 Java 8 中内置的 java.time 的大部分功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7项目,并在 ThreeTenABP 中进一步适应早期的 Android。
【解决方案2】:

所以,答案比我想象的要简单。

private void setTimestamp(String timeCreated) {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    try {
        Date timeCreatedDate = dateFormat.parse(timeCreated);
        timeStamp = (String) DateUtils.getRelativeTimeSpanString(timeCreatedDate.getTime(),
                                  System.currentTimeMillis(), 
                                  DateUtils.SECONDS_IN_MILLIS);
    } catch ( ParseException e) {}
}

这会起作用的。

【讨论】:

    猜你喜欢
    • 2017-10-09
    • 2012-02-20
    • 1970-01-01
    • 2023-03-26
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    相关资源
    最近更新 更多