如何将ISO8601格式转换为毫秒?

时间:2014-10-23 01:30:11

标签: java android datetime

我很惊讶我还没有找到一种非常简单的方法,考虑到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转换为毫秒。

2 个答案:

答案 0 :(得分:10)

TL;博士

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

One-Liner in java.time

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

InstantUTC中时间轴上的一个时刻,分辨率为nanoseconds。你可以ask it for a count of milliseconds epoch(1970年的第一个时刻UTCdirectly parse。但请记住,Instant可能有额外的数据,纳秒比毫秒更精细。因此,可能会在一小部分时间内丢失数据

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

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

您可以通过调用toEpochMilli

将其转换为自UTC 1970年第一时刻以来的毫秒数

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

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

要按小时 - 分钟 - 秒计算已用时间,请使用between课程。及时提供Joda-Time方法。

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

Joda-Time中的单线

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

使用ISO 8601 2.5库:

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

Joda-Time默认解析并生成{{3}}个字符串。 Joda-Time适用于Android。 java.util.Date / .Calendar类出了名的麻烦,令人困惑和有缺陷。避免它们。

答案 1 :(得分:5)

所以,事实证明答案比我想象的要简单。

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) {}
}

那将会工作。