问题描述
我正在尝试格式化日期时间戳,包括带有冒号的时区。我做了几次实验以获得结果。这就是我发现的东西。
Date date = new Date();
String zoneddatetimeFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
SimpleDateFormat sdf = new SimpleDateFormat(zoneddatetimeFormat);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(sdf.format(new Date(date.getTime())));
如果将时区设置为UTC,则将获得如下时间戳:
2020-11-03T21:14:07.449Z
但是如果时区不是UTC
Date date = new Date();
String zoneddatetimeFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
SimpleDateFormat sdf = new SimpleDateFormat(zoneddatetimeFormat);
System.out.println(sdf.format(new Date(date.getTime())));
时间戳如下:2020-11-03T22:19:43.804+01:00
我想知道是否有可能在UTC时区之类的时间戳:2020-11-03T21:14:07.449+00:00
而不是以大写的Z
结尾?
解决方法
您可以使用Java 8 Date / Time API,该API受Joda Time库的影响很大(显然也有some overlap in developer effort),但是在某些方面有所不同。与Joda Time不同,Java 8 Date / Time API是Java固有的。
DateTimeFormatter类具有以下模式字母:
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00
在您的情况下,小写的x
应该给出您想要的结果。
示例代码:
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.ZoneId;
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSxxx");
ZoneId zone = ZoneId.of("UTC");
ZonedDateTime d = ZonedDateTime.now(zone);
System.out.println(d.format(f));
输出:
2020-11-03T22:31:10.928+00:00
值得一读package description for the Java 8 Date and Time API来了解API的一般原理,这与java.util Date和Calendar对象的原理有点不同。
简而言之,主要思想是该API中的所有日期和时间对象都是不可变的,并且如果您要修改或创建日期,则可以使用工厂方法(如{{1})创建其他日期和时间对象}或类似of
的函数,它们返回datetime对象的副本,但指定的字段已更改。
一些重要的课程:
with
-时间戳记Instant
-不带时间的日期,或对偏移量或时区的任何引用LocalDate
-没有日期的时间,或对偏移量或时区的任何引用LocalTime
-组合日期和时间,但仍然没有任何偏移或时区LocalDateTime
-带有时区的“完整”日期时间,已解决与UTC /格林威治时间的偏移量ZonedDateTime
-代表时区
要将Java.util.Date对象转换为Java 8 Date / Time API中的相应对象,请参见:Convert java.util.Date to java.time.LocalDate