如何将 ISO8601 格式转换为毫秒?
Posted
技术标签:
【中文标题】如何将 ISO8601 格式转换为毫秒?【英文标题】:How to convert ISO8601 format into milliseconds? 【发布时间】: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 我不是反对者。但我怀疑投票否决可能是由于 *** 上数百个问题和答案处理了这个主题。 @PM77-1 android 中没有 Java 8 和 java.time。 【参考方案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 领导。
Instant
是UTC 时间线上的一个时刻,分辨率为nanoseconds。您可以从其epoch 中ask it for a count of milliseconds(UTC 中的 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.Date
、Calendar
和 SimpleDateFormat
。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.*
类。
从哪里获得 java.time 类?
Java SE 8、Java SE 9、Java SE 10 及更高版本 内置。 标准 Java API 的一部分,带有捆绑实现。 Java 9 添加了一些小功能和修复。 Java SE 6 和 Java SE 7 ThreeTen-Backport 中的大部分 java.time 功能都向后移植到 Java 6 和 7。 Android java.time 类的 Android 捆绑包实现的更高版本。 对于早期的 Android (ThreeTenABP 项目采用 ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…。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)
这会起作用的。
【讨论】:
以上是关于如何将 ISO8601 格式转换为毫秒?的主要内容,如果未能解决你的问题,请参考以下文章
如何配置 web api 的 json 序列化器将日期时间转换为 ISO 8601 格式?
一种将当前日期时间转换为 ISO 8601 格式的优雅方法 [重复]
如何在 Pandas 数据框中将日期转换为 ISO-8601 DateTime 格式