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

Dav*_*vid 9 java datetime android

考虑到ISO8601在JSON中的使用频率,我还没有找到一个非常简单的方法,我感到非常惊讶.

基本上,我正在使用一个看起来像这样的字符串:2014-10-23T00:35:14.800Z并将其转换为类似的字符串50 minutes ago.

首先,我要改变2014-10-23T00:35:14.800Z2014-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);
}
Run Code Online (Sandbox Code Playgroud)

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

Bas*_*que 12

TL;博士

Instant.parse( "2014-10-23T00:35:14.800Z" )
       .toEpochMilli()
Run Code Online (Sandbox Code Playgroud)

One-Liner在java.time中

java.time框架是建立在Java 8和更高版本.这些新类取代了与最早版本的Java捆绑在一起的旧日期时间类,例如java.util.Date/.Calendar.请参阅教程.java.time类还取代了非常成功的Joda-Time库,由一些相同的人构建,包括由同一个Stephen Colbourne领导.

An InstantUTC时间轴上的一个时刻,分辨率为纳秒.你可以从它的纪元(UTC的1970年第一个时刻)开始询问它的毫秒数.但请记住,可能有额外的数据,纳秒比毫秒更精细.因此,您可能会在一小部分时间内丢失数据.Instant

解析/生成字符串时,java.time类使用标准的ISO 8601格式.无需指定格式模式.本Instant类可以直接解析字符串.

Instant.parse( "2014-10-23T00:35:14.800Z" )
Run Code Online (Sandbox Code Playgroud)

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

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

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

要以小时 - 分钟 - 秒计算经过的时间,请使用该Duration课程.between及时喂它的方法.

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

在Joda-Time的单线

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

使用Joda-Time 2.5库:

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

Joda-Time 默认分析并生成ISO 8601字符串.Joda-Time适用于Android.java.util.Date/.Calendar类出了名的麻烦,令人困惑和有缺陷.避免他们.

  • 自 API 26 起,“Instant”仅在 Android 上可用 (2认同)

Dav*_*vid 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) {}
}
Run Code Online (Sandbox Code Playgroud)

可以的