使用 java.time 根据时区转换时间
Convert time based on timezone using java.time
如何根据 LocalDateTime 中的时区更改时间,这里我已经建立了一个时区为 EST 的日期,现在我需要找到对应时间的UTC。请帮我解决这个问题
String str = "16Jun2015_153556";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMyyyy_HHmmss");
formatter.withZone(ZoneId.of("EST5EDT"));
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
您不应该考虑 LocalDateTime
的 "changing the time zone" - LocalDateTime
没有 有 时区。相反,您应该从 LocalDateTime
和时区 (ZoneId
) 构建 ZonedDateTime
。首先删除 formatter.withZone
调用,然后使用:
ZonedId zone = ZoneId.of("EST5EDT"); // Or preferrably "America/New_York"
ZonedDateTime zoned = ZonedDateTime.of(dateTime, zone);
然后你可以将其转换为瞬间,或者使用:
ZonedDateTime utc = zoned.withZoneSameInstant(ZoneOffset.UTC);
例如:
import java.time.*;
import java.time.format.*;
public class Test {
public static void main(String[] args) {
String str = "16Jun2015_153556";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMyyyy_HHmmss");
ZoneId zone = ZoneId.of("America/New_York");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
ZonedDateTime zoned = ZonedDateTime.of(dateTime, zone);
// Both of these print 2015-06-16T19:35:56Z
System.out.println(zoned.toInstant());
System.out.println(zoned.withZoneSameInstant(ZoneOffset.UTC));
}
}
这个答案可能比 Jon Skeet 的正确答案更有条理。在我上面的评论中,我还指出不要忽视 DateTimeFormatter
的不可变性质,因此请始终将任何以 "with...()" 为前缀的方法的结果分配给相同类型的变量。
// parsing your string input
// NO!!! timezone is needed in this step because LocalDateTime is just without timezone
String str = "16Jun2015_153556";
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("ddMMMuuuu_HHmmss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(str, formatter);
System.out.println(ldt); // your input as java.time-object: 2015-06-16T15:35:56
然后您将本地日期时间分配给 EST 区。使用 IANA 符号 "America/New_York" 比使用过时的形式 "EST5EDT" 更安全(后者仅支持固定的 dst 规则,没有任何历史原始偏移量的历史记录)。
ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/New_York"));
最后,您将中间全局时间戳转换回偏移量 UTC+00 处的本地日期时间,保留相同的物理时间:
LocalDateTime utc = zdt.withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
System.out.println(utc); // 2015-06-16T19:35:56
如何根据 LocalDateTime 中的时区更改时间,这里我已经建立了一个时区为 EST 的日期,现在我需要找到对应时间的UTC。请帮我解决这个问题
String str = "16Jun2015_153556";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMyyyy_HHmmss");
formatter.withZone(ZoneId.of("EST5EDT"));
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
您不应该考虑 LocalDateTime
的 "changing the time zone" - LocalDateTime
没有 有 时区。相反,您应该从 LocalDateTime
和时区 (ZoneId
) 构建 ZonedDateTime
。首先删除 formatter.withZone
调用,然后使用:
ZonedId zone = ZoneId.of("EST5EDT"); // Or preferrably "America/New_York"
ZonedDateTime zoned = ZonedDateTime.of(dateTime, zone);
然后你可以将其转换为瞬间,或者使用:
ZonedDateTime utc = zoned.withZoneSameInstant(ZoneOffset.UTC);
例如:
import java.time.*;
import java.time.format.*;
public class Test {
public static void main(String[] args) {
String str = "16Jun2015_153556";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMyyyy_HHmmss");
ZoneId zone = ZoneId.of("America/New_York");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
ZonedDateTime zoned = ZonedDateTime.of(dateTime, zone);
// Both of these print 2015-06-16T19:35:56Z
System.out.println(zoned.toInstant());
System.out.println(zoned.withZoneSameInstant(ZoneOffset.UTC));
}
}
这个答案可能比 Jon Skeet 的正确答案更有条理。在我上面的评论中,我还指出不要忽视 DateTimeFormatter
的不可变性质,因此请始终将任何以 "with...()" 为前缀的方法的结果分配给相同类型的变量。
// parsing your string input
// NO!!! timezone is needed in this step because LocalDateTime is just without timezone
String str = "16Jun2015_153556";
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("ddMMMuuuu_HHmmss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(str, formatter);
System.out.println(ldt); // your input as java.time-object: 2015-06-16T15:35:56
然后您将本地日期时间分配给 EST 区。使用 IANA 符号 "America/New_York" 比使用过时的形式 "EST5EDT" 更安全(后者仅支持固定的 dst 规则,没有任何历史原始偏移量的历史记录)。
ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/New_York"));
最后,您将中间全局时间戳转换回偏移量 UTC+00 处的本地日期时间,保留相同的物理时间:
LocalDateTime utc = zdt.withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
System.out.println(utc); // 2015-06-16T19:35:56