Ada*_*dam 25 java html5 datetime rfc3339 date-parsing
我正在尝试解析从HTML5 datetime输入字段返回的值作为值.在Opera中试一试看一个例子.返回的日期如下:2011-05-03T11:58:01Z.
我想将其解析为Java Date或Calendar Object.
理想情况下,解决方案应该包含以下内容:
Bas*_*que 16
Instant.parse( "2011-05-03T11:58:01Z" )
Run Code Online (Sandbox Code Playgroud)
实际上,RFC 3339仅仅是实际标准ISO 8601的简介.
RFC的不同之处在于它故意违反ISO 8601以允许零小时(-00:00)的负偏移并且给出"偏移未知"的语义含义.这个语义对我来说似乎是一个非常糟糕的主意.我建议坚持使用更合理的ISO 8601规则.在ISO 8601中,没有任何偏移意味着偏移是未知的 - 一个明显的含义,而RFC规则是深奥的.
在解析/生成字符串时,现代java.time类默认使用ISO 8601格式.
您的输入字符串表示UTC的时刻.在Z上月底是短期的Zulu,并指UTC.
Instant(不是Date)现代类Instant代表UTC的一个时刻.该类替换java.util.Date并使用更精细的纳秒分辨率而不是毫秒.
Instant instant = Instant.parse( "2011-05-03T11:58:01Z" ) ;
Run Code Online (Sandbox Code Playgroud)
ZonedDateTime(不是Calendar)要通过特定地区(时区)的人们所使用的挂钟时间来查看同一时刻,请应用a ZoneId来获取ZonedDateTime.这个类ZonedDateTime取代了这个java.util.Calendar类.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
Run Code Online (Sandbox Code Playgroud)
我强烈建议尽可能避免使用旧版日期时间类.但是,如果您必须与尚未更新到java.time的旧代码进行交互操作,则可以来回转换.调用添加到旧类的新方法.
Instant替换java.util.Date.
java.util.Date myJUDate = java.util.Date.from( instant ) ; // From modern to legacy.
Instant instant = myJUDate.toInstant() ; // From legacy to modern.
Run Code Online (Sandbox Code Playgroud)
ZonedDateTime替换GregorianCalendar.
java.util.GregorianCalendar myGregCal = java.util.GregorianCalendar.from( zdt ) ; // From modern to legacy.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ; // From legacy to modern.
Run Code Online (Sandbox Code Playgroud)
如果你有一个java.util.Calendar实际上是GregorianCalendar,铸造.
java.util.GregorianCalendar myGregCal = ( java.util.GregorianCalendar ) myCal ; // Cast to the concrete class.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ; // From legacy to modern.
Run Code Online (Sandbox Code Playgroud)
关于你的问题的具体问题......
该java.time类Java中内嵌的8,9,10,和更高版本.稍后的Android中还包含一个实现.对于早期的Java和早期的Android,请参阅本答案的下一部分.
各种java.time类处理我所知道的每种ISO 8601格式.他们甚至处理了一些格式,这些格式在标准的后续版本中神秘地消失了.
对于其它的格式,见parse和toString各种类的方法,例如LocalDate,OffsetDateTime等.此外,搜索Stack Overflow,因为有很多关于此主题的示例和讨论.
要验证输入字符串,请捕获DateTimeParseException.
try {
Instant instant = Instant.parse( "2011-05-03T11:58:01Z" ) ;
} catch ( DateTimeParseException e ) {
… handle invalid input
}
Run Code Online (Sandbox Code Playgroud)
该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.
现在处于维护模式的Joda-Time项目建议迁移到java.time类.
要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.
您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*
从哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.
Paŭ*_*ann 13
因此,原则上这将使用不同的SimpleDateFormat模式来完成.
这里是RFC 3339中各个声明的模式列表:
yyyyMMddHHmmss.SSS (S毫秒表示,虽然-目前尚不清楚是否有更多或者这些不超过3位会发生什么.)+02:00好像不支持 - 相反它支持格式+0200,GMT+02:00一些命名时区使用z和Z.)'Z' 不支持其他时区) - 在使用format.setTimezone(TimeZone.getTimeZone("UTC"))之前应该使用.)HH:mm:ss或HH:mm:ss.SSS.HH:mm:ss'Z'或HH:mm:ss.SSS'Z'.yyyy-MM-ddyyyy-MM-dd'T'HH:mm:ss'Z'或yyyy-MM-dd'T'HH:mm:ss.SSS'Z'我们可以看到,这似乎无法解析所有内容.也许RFC3339DateFormat从头开始实现一个更好的主意(使用正则表达式,为简单起见,或者手工解析,以提高效率).
刚刚发现Google在Google HTTP Client Library中实现了Rfc3339解析器
经过测试。它很好地解析了亚秒级的时间片段。
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import com.google.api.client.util.DateTime;
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.withZone(ZoneId.of("UTC"));
@Test
public void test1e9Parse() {
String timeStr = "2018-04-03T11:32:26.553955473Z";
DateTime dateTime = DateTime.parseRfc3339(timeStr);
long millis = dateTime.getValue();
String result = formatter.format(new Date(millis).toInstant());
assert result.equals("2018-04-03T11:32:26.553Z");
}
@Test
public void test1e3Parse() {
String timeStr = "2018-04-03T11:32:26.553Z";
DateTime dateTime = DateTime.parseRfc3339(timeStr);
long millis = dateTime.getValue();
String result = formatter.format(new Date(millis).toInstant());
assert result.equals("2018-04-03T11:32:26.553Z");
}
@Test
public void testEpochSecondsParse() {
String timeStr = "2018-04-03T11:32:26Z";
DateTime dateTime = DateTime.parseRfc3339(timeStr);
long millis = dateTime.getValue();
String result = formatter.format(new Date(millis).toInstant());
assert result.equals("2018-04-03T11:32:26.000Z");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23784 次 |
| 最近记录: |