simpledateformat用'Z'文字parsingdate
我试图parsing一个看起来像这样的date:
2010-04-05T17:16:00Z
这是每个http://www.ietf.org/rfc/rfc3339.txt的有效date。 “Z”字面意味着UTC是指定时间的首选参考点。
如果我尝试使用SimpleDateFormat和这种模式parsing它:
yyyy-MM-dd'T'HH:mm:ss
它将被parsing为2010年4月5日星期一17:16:00
SimpleDateFormat无法parsing这些模式的string:
yyyy-MM-dd'T'HH:mm:ssz yyyy-MM-dd'T'HH:mm:ssZ
我可以明确地设置TimeZone使用SimpleDateFormat来获得预期的输出,但我不认为这是必要的。 有什么我失踪? 有没有其他dateparsing器?
在该模式中,包含“z”date时间分量表示时区格式需要符合通用时区 “标准”,例如Pacific Standard Time; PST; GMT-08:00
Pacific Standard Time; PST; GMT-08:00
Pacific Standard Time; PST; GMT-08:00
。
“Z”表示时区符合RFC 822时区标准,例如-0800
。
我认为你需要一个DatatypeConverter …
@Test public void testTimezoneIsGreenwichMeanTime() throws ParseException { final Calendar calendar = javax.xml.bind.DatatypeConverter.parseDateTime("2010-04-05T17:16:00Z"); TestCase.assertEquals("gotten timezone", "GMT+00:00", calendar.getTimeZone().getID()); }
Java不能正确parsingISOdate。
类似麦肯齐的答案。
parsing之前只需修复Z
码
String string = "2013-03-05T18:05:05.000Z"; String defaultTimezone = TimeZone.getDefault().getID(); Date date = (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).parse(string.replaceAll("Z$", "+0000")); System.out.println("string: " + string); System.out.println("defaultTimezone: " + defaultTimezone); System.out.println("date: " + (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")).format(date));
结果
string: 2013-03-05T18:05:05.000Z defaultTimezone: America/New_York date: 2013-03-05T13:05:05.000-0500
你parsing的date是ISO8601格式。
在java 7中,读取和应用时区后缀的模式应该是yyyy-MM-dd'T'HH:mm:ssX
TL;博士
Instant.parse ( "2010-04-05T17:16:00Z" )
ISO 8601标准
您的string符合ISO 8601标准(其中提到的RFC 3339是一个configuration文件)。
避免juDate
与Java捆绑在一起的java.util.Date和.Calendar类是非常麻烦的。 避免他们。
而是使用Java 8中的Joda-Time库或新的java.time包。两者都使用ISO 8601作为parsing和生成date – 时间值的string表示的默认值。
java.time
内置于Java 8及更高版本中的java.time框架取代了麻烦的旧java.util.Date/.Calendar类。 新课程的灵感来自非常成功的Joda-Time框架,其目标是作为其后继者,在概念上相似但重新devise。 由JSR 310定义。 由ThreeTen-Extra项目扩展。 参见教程 。
java.time中的Instant
类表示UTC时区中时间轴上的某一时刻。
inputstring末尾的Z
表示代表UTC
Zulu
。 这样的string可以直接由Instant
类parsing,不需要指定格式化程序。
String input = "2010-04-05T17:16:00Z"; Instant instant = Instant.parse ( input );
转储到控制台。
System.out.println ( "instant: " + instant );
即时:2010-04-05T17:16:00Z
从那里你可以申请一个时区( ZoneId
)来调整这个Instant
到ZonedDateTime
。 search堆栈溢出的讨论和例子。
如果您必须使用java.util.Date
对象,则可以通过调用添加到旧类(如静态方法java.util.Date.from( Instant )
的新转换方法进行转换。
java.util.Date date = java.util.Date.from( instant );
乔达时间
Joda-Time 2.5中的例子
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ): DateTime dateTime = new DateTime( "2010-04-05T17:16:00Z", timeZone );
转换为UTC。
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
如有必要,转换为java.util.Date。
java.util.Date date = dateTime.toDate();
“X”只有在部分秒不存在的情况下才有效:即SimpleDateFormat模式
“YYYY-MM-dd'T'HH:MM:SSX”
将正确parsing
“2008-01-31T00:00:00Z”
但
“YYYY-MM-dd'T'HH:MM:ss.SX”
不会parsing
“2008-01-31T00:00:00.000Z”
可悲的是,具有部分秒的date时间似乎不是一个有效的ISOdate: http : //en.wikipedia.org/wiki/ISO_8601
根据Java 7 API的Date and Time Patterns表中的最后一行
X时区ISO 8601时区-08; -0800; -08:00
对于ISO 8601时区,您应该使用X(-08或Z); XX(-0800或Z); 和XXX(-08:00或Z)来parsing你的“2010-04-05T17:16:00Z”是“yyyy-MM-dd'T'HH:mm:ssX”或“yyyy-MM-dd” T'HH:mm:ssXX“或”yyyy-MM-dd'T'HH:mm:ssXXX“应该有效。
System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse("2010-04-05T17:16:00Z")); System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXX").parse("2010-04-05T17:16:00Z")); System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse("2010-04-05T17:16:00Z"));
将正确打印出“2010年4月5日13:16:00美国东部时间2010年”
时区应该类似于“GMT + 00:00”或0000,以便被SimpleDateFormat正确parsing – 您可以用此构造replaceZ.
restlet项目包括一个可以parsingRFC 3339date的InternetDateFormat类。
Restlet InternetDateFormat
虽然,你可能只是想在parsing它之前用“UTC”replace尾随的“Z”。
我提供了另外一个答案,我通过api-client-library
了Google
try { DateTime dateTime = DateTime.parseRfc3339(date); dateTime = new DateTime(new Date(dateTime.getValue()), TimeZone.getDefault()); long timestamp = dateTime.getValue(); // get date in timestamp int timeZone = dateTime.getTimeZoneShift(); // get timezone offset } catch (NumberFormatException e) { e.printStackTrace(); }
安装指南,
https://developers.google.com/api-client-library/java/google-api-java-client/setup#download
DateTime
类的源代码,
https://github.com/google/google-http-java-client/blob/master/google-http-client/src/main/java/com/google/api/client/util/DateTime.java
DateTime
unit testing,
https://github.com/google/google-http-java-client/blob/master/google-http-client/src/test/java/com/google/api/client/util/DateTimeTest.java#L121
关于JSR-310,另一个感兴趣的项目可能是三年 。
JSR-310为Java SE 8提供了一个新的date和时间库。该项目是Java SE 6和7的后端。
如果您正在使用Android项目,则可能需要签出ThreeTenABP库 。
compile "com.jakewharton.threetenabp:threetenabp:${version}"
JSR-310作为java.time。*包被包含在Java 8中。 它完全取代了Java和Android中的日历和日历API。 JSR-310被其创build者Stephen Colebourne从Java库中移植到了Java 6,该库从此被改编。
在Java 8下使用预定义的DateTimeFormatter.ISO_DATE_TIME
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; ZonedDateTime result = ZonedDateTime.parse("2010-04-05T17:16:00Z", formatter);
我想它是最简单的方法
由于Java 8只是使用ZonedDateTime.parse("2010-04-05T17:16:00Z")