在 Java >= 8 中,您可以使用 new java.time API。
输入包含:
在新的java.time API 中,有lots of different types 的日期/时间对象。在这种情况下,我们可以选择使用 java.time.Instant(表示自 unix 纪元以来的纳秒计数)或 java.time.OffsetDateTime(表示将 Instant 转换为特定偏移量中的日期/时间)。
为了解析String,我使用java.time.format.DateTimeFormatterBuilder 来创建java.time.format.DateTimeFormatter。我还使用java.time.temporal.ChronoField 来指定我正在解析的字段:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// epoch seconds
.appendValue(ChronoField.INSTANT_SECONDS)
// milliseconds
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
// offset
.appendPattern("xx")
// create formatter
.toFormatter();
我还使用正则表达式从输入 String 中提取相关部分(尽管您也可以使用 substring() 来获取它):
String s = "/Date(1325134800000-0500)/";
// get just the "1325134800000-0500" part - you can also do s.substring(6, 24)
s = s.replaceAll(".*/Date\\(([\\d\\+\\-]+)\\)/.*", "$1");
然后我就可以解析成我想要的类型了:
// parse to Instant
Instant instant = Instant.from(fmt.parse(s));
// parse to OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(s, fmt);
Instant 等价于 2011-12-29T05:00:00Z(Instant 只是时间线中的一个点,您可以认为它始终是 UTC)。
OffsetDateTime 具有相同的瞬间,但转换为 -0500 偏移量,因此其值为 2011-12-29T00:00-05:00。但Instant 和OffsetDateTime 都代表同一个时间点。
要转换为java.util.Date,请使用Instant:
// convert to java.util.Date
Date date = Date.from(instant);
// if you have an OffsetDateTime, you can do this:
Date date = Date.from(odt.toInstant());
那是因为java.util.Datehas no timezone/offset information 仅表示自 unix 纪元以来的毫秒数(与 Instant 的概念相同),因此可以轻松地从 Instant 转换。
Java 6 和 7
对于 Java 6 和 7,您可以使用 ThreeTen Backport,这是 Java 8 新日期/时间类的一个很好的反向移植。对于Android,您还需要ThreeTenABP(更多关于如何使用它here)。
与 Java 8 的区别在于包名(在 Java 8 中是 java.time,而在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp),但类和方法 names 是相同的。所以格式化程序的创建和Instant和OffsetDateTime的解析代码是一样的。
另一个区别是,在 Java java.util.Date 类没有 from() 方法。但是您可以使用org.threeten.bp.DateTimeUtils 类进行转换:
// convert to java.util.Date
Date date = DateTimeUtils.toDate(instant);
// or from the OffsetDateTime
Date date = DateTimeUtils.toDate(odt.toInstant());