我需要在ISO 8601中获取具有SS毫秒和HH:MM时区的当前日期
完整的日期加上小时、分钟、秒和 第二个:YYYY-MM-DDThh:mm:ss.sTZD (例如 1997-07-16T19:20:30。45+01:00)
参见:http://www.w3.org/TR/NOTE-datetime
我尝试了不同的方法,但我无法获得正确的毫秒和时区数字:
DateFormat df=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSZZ");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
df.format(new Date());
JAVA 结果:2012-11-24T21:19:27。758+0000
阿帕奇结果:2012-11-24T21:19:27。758+00:00(Apache Commons FastDateFormat)
实际上JDK中有一个类可以处理解析和格式化ISO8601:
import javax.xml.bind.DatatypeConverter;
DatatypeConverter.printDateTime(new GregorianCalendar())
//2012-11-24T22:42:03.142+01:00
tl;博士
当前时刻,世界协调时
使用java.time.Instant
以精细到纳秒的分辨率捕获当前时刻。
Instant.now() // Capture the current moment in UTC, with a resolution as fine as nanoseconds. Typically captured in microseconds in Java 9 and later, milliseconds in Java 8.
.toString() // Generate a `String` representing the value of this `Instant` in standard ISO 8601 format.
2018-01-23T12:34:56.123456Z
最后的Z
:
- 表示世界协调时,
- 相当于
+00:00
偏移量, - 发音为"祖鲁语",并且
- 由ISO 8601标准以及军事等其他领域定义。
当前力矩,特定偏移
如果由于某种异常原因,您必须调整为特定的 UTC 偏移量,请使用OffsetDateTime
,传递ZoneOffset
。
OffsetDateTime.now( // Capture the current moment.
ZoneOffset.ofHours( 1 ) // View the current moment adjusted to the wall-clock time of this specific offset-from-UTC. BTW, better to use time zones, generally, than a mere offset-from-UTC.
)
.toString() // Generate a `String` in standard ISO 8601 format.
2018-07-08T21:13:10.723676+01:00
当前时刻,截断为米利斯
对于毫秒分辨率,截断。通过ChronoUnit
枚举指定分辨率。
OffsetDateTime.now(
ZoneOffset.ofHours( 1 )
)
.truncatedTo( // Lop off finer part of the date-time. We want to drop any microseconds or nanoseconds, so truncate to milliseconds. Using the immutable objects pattern, so a separate new `OffsetDateTime` object is generated based on the original object’s values.
ChronoUnit.MILLIS // Specify your desired granularity via `ChronoUnit` enum.
)
.toString()
2018-07-08T21:13:10.723+01:00
java.time
Java 8 及更高版本中内置的 java.time 框架在解析或生成日期时间值的文本表示时默认使用 ISO 8601
。Instant
是时间轴上的一个时刻,以 UTC 为单位,分辨率为纳秒。
Instant instant = Instant.now();
在 Java8 中以毫秒的分辨率捕获当前时刻,在 Java 9 及更高版本中,通常以微秒的分辨率捕获当前时刻,具体取决于主机硬件时钟和操作系统的功能。如果您特别想要毫秒分辨率,请截断任何微秒或纳秒。
Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ;
但是您需要一个特定的 UTC 偏移量。因此,请指定一个ZoneOffset
以获取OffsetDateTime
。
ZoneOffset offset = ZoneOffset( "+01:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , offset );
同样,如果您特别想要毫秒分辨率而不是微秒或纳秒,请截断。
odt = odt.truncatedTo( ChronoUnit.MILLIS ) ; // Replace original `OffsetDateTime` object with new `OffsetDateTime` object based on the original but with any micros/nanos lopped off.
要生成 ISO 8601 字符串,只需调用toString
。
String output = odt.toString();
转储到控制台。在输出中注意小时如何向前滚动作为对+01:00
偏移量的调整,甚至滚动到午夜,因此日期从 12 日更改为 13 日。
System.out.println ( "instant: " + instant + " | offset: " + offset + " | odt: " + odt );
即时: 2016-04-12T23:12:24.015Z | 偏移: +01:00| ODT: 2016-04-13T00:12:24.015+01:00
划 作
顺便说一下,最好使用时区(如果已知),而不仅仅是偏移量。时区 特定地区人民使用的过去、现在和未来偏移量变化的历史记录。
在java.time中,这意味着应用ZoneId
来获取ZonedDateTime
。
ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
或者跳过Instant
,作为快捷方式。
ZonedDateTime zdt = ZonedDateTime.now( zoneId ) ;
生成一个以文本方式表示该ZonedDateTime
对象的值的String
。默认情况下使用的格式是标准的 ISO 8601 格式,明智地扩展以将区域名称附加到方括号中。
zdt.toString(): 2018-07-08T22:06:58.780923+02:00[欧洲/巴黎]
对于其他格式,请使用DateTimeFormatter
类。
关于java.time
java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧传统日期时间类,如java.util.Date
、Calendar
和SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到 java.time 类。
要了解更多信息,请参阅Oracle 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。
您可以直接与数据库交换java.time对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要java.sql.*
类。
从哪里获得java.time类?
Java SE 8、Java SE- 9、Java SE 10及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9添加了一些小功能和修复。
Java SE 6 和 Java SE 7 大部分 - java.time 功能在ThreeTen-Backport中向后移植到 Java 6 和 7。
Android- 更高版本的java.time类的 Android 捆绑实现。
- 对于早期的Android(<26),ThreeTenABP项目适应了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP...。
ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
等。