What is this date format? 2011-08-12T20:17:46.384Z
我有以下日期:
java.text.ParseException: Unparseable date:"2011-08-12T20:17:46.384Z"
我想我应该使用SimpleDateFormat进行解析,但我必须首先知道格式字符串。 到目前为止,我所拥有的只是
T只是将日期与时间分开的文字,Z表示"零小时偏移",也称为"祖鲁时间"(UTC)。如果你的字符串总是有一个"Z",你可以使用:
1 2 3 | SimpleDateFormat format = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); format.setTimeZone(TimeZone.getTimeZone("UTC")); |
或者使用Joda Time,您可以使用
TL;博士
输入字符串使用标准ISO 8601格式。
1 | Instant.parse ("2011-08-12T20:17:46.384Z" ) |
ISO 8601
这种格式由合理的实用标准ISO 8601定义。
java.time
与最早版本的Java捆绑在一起的旧日期时间类已被证明设计糟糕,令人困惑且麻烦。避免他们。
相反,请使用Java 8及更高版本中内置的java.time框架。 java.time类取代了旧的日期时间类和非常成功的Joda-Time库。
在解析/生成日期时间值的文本表示时,java.time类默认使用ISO 8601。
1 | Instant instant = Instant.parse ("2011-08-12T20:17:46.384Z" ) ; |
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
-
Java SE 8,Java SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小功能和修复。
-
Java SE 6和Java SE 7
- 许多java.time功能都被反向移植到Java 6& 7在ThreeTen-Backport。
-
Android的
- 更高版本的Android捆绑java.time类的实现。
- 对于早期的Android,ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP ....
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的类,例如
不确定Java解析,但那是ISO8601:http://en.wikipedia.org/wiki/ISO_8601
还有其他方法可以解析它而不是第一个答案。要解析它:
(1)如果要获取有关日期和时间的信息,可以将其解析为
1 2 3 4 | // ZonedDateTime's default format requires a zone ID(like [Australia/Sydney]) in the end. // Here, we provide a format which can parse the string correctly. DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME; ZonedDateTime zdt = ZonedDateTime.parse("2011-08-12T20:17:46.384Z", dtf); |
要么
1 2 3 4 5 6 7 8 | // 'T' is a literal. // 'X' is ISO Zone Offset[like +01, -08]; For UTC, it is interpreted as 'Z'(Zero) literal. String pattern ="yyyy-MM-dd'T'HH:mm:ss.SSSX"; // since no built-in format, we provides pattern directly. DateFormat df = new SimpleDateFormat(pattern); Date myDate = df.parse("2011-08-12T20:17:46.384Z"); |
(2)如果您不关心日期和时间,只想将信息视为以纳秒为单位的时刻,那么您可以使用
1 2 3 | // The ISO format without zone ID is Instant's default. // There is no need to pass any format. Instant ins = Instant.parse("2011-08-12T20:17:46.384Z"); |
此技术将java.util.Date转换为UTC格式(或任何其他格式)并再次返回。
像这样定义一个类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import java.util.Date; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; public class UtcUtility { public static DateTimeFormatter UTC = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZoneUTC(); public static Date parse(DateTimeFormatter dateTimeFormatter, String date) { return dateTimeFormatter.parseDateTime(date).toDate(); } public static String format(DateTimeFormatter dateTimeFormatter, Date date) { return format(dateTimeFormatter, date.getTime()); } private static String format(DateTimeFormatter dateTimeFormatter, long timeInMillis) { DateTime dateTime = new DateTime(timeInMillis); String formattedString = dateTimeFormatter.print(dateTime); return formattedString; } |
}
然后像这样使用它:
1 |
要么
如果需要,您还可以定义其他日期格式(不仅仅是UTC)
您可以使用以下示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | String date ="2011-08-12T20:17:46.384Z"; String inputPattern ="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; String outputPattern ="yyyy-MM-dd HH:mm:ss"; LocalDateTime inputDate = null; String outputDate = null; DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(inputPattern, Locale.ENGLISH); DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(outputPattern, Locale.ENGLISH); inputDate = LocalDateTime.parse(date, inputFormatter); outputDate = outputFormatter.format(inputDate); System.out.println("inputDate:" + inputDate); System.out.println("outputDate:" + outputDate); |