全球划分24个时区,不同国家所处的时区也不同,我国采取的时区是东八区即北京时间 (GMT+8 ,UTC+8), 经常做海外业务的同事就会遇到时区转换和夏令营的问题,刚好今天我也遇到了,查阅了网上很多办法,最终采取网友的方法并做一些修改,希望可以帮到各位。
// 获取标准时区
private static String getZoneDesc(TimeZone destzone) {
Objects.requireNonNull(destzone);
int Offset = destzone.getRawOffset() / (1000 * 60 * 60);
if (Offset <= 0) {
return "GMT" + String.valueOf(Offset);
} else {
return "GMT+" + String.valueOf(Offset);
}
}
// 获取指定时间的 指定时区时间 参照点:默认时区
public LocalDateTime getZongTime(LocalDateTime srcTime, ZoneId src, ZoneId dest) {
Objects.requireNonNull(dest);
ZonedDateTime z1 = null;
z1 = srcTime.atZone(ZoneId.systemDefault());
ZonedDateTime z2 = z1.withZoneSameInstant(dest);
// 处理重叠问题
long hours = Duration.between(z2.withEarlierOffsetAtOverlap(), z2.withLaterOffsetAtOverlap()).toHours();
z2 = z2.plusHours(hours);
System.out.println(dest.getId() + "对应得标准时区:" + getZoneDesc(TimeZone.getTimeZone(dest)));
System.out.println("目标时区" + dest + "的时间" + z2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
System.out.println("-------------");
return srcTime;
}
@Test
public void test() throws Exception {
// 预计不在夏令时 2017-03-13 01:59:59
LocalDateTime time4 = LocalDateTime.of(2016, 3, 13, 14, 59, 59);
getZongTime(time4, ZoneId.of("GMT+8"), ZoneId.of("America/New_York"));
// 预计在夏令时 2017-03-13 03:00:00
LocalDateTime time1 = LocalDateTime.of(2016, 3, 13, 15, 00, 00);
getZongTime(time1, ZoneId.of("GMT+8"), ZoneId.of("America/New_York"));
// 预计在夏令时 2017-11-06 02:59:59
LocalDateTime time2 = LocalDateTime.of(2016, 11, 6, 14, 59, 59);
getZongTime(time2, ZoneId.of("GMT+8"), ZoneId.of("America/New_York"));
// 预计不在夏令时2017-11-06 02:00:00
LocalDateTime time3 = LocalDateTime.of(2016, 11, 6, 15, 00, 00);
getZongTime(time3, ZoneId.of("GMT+8"), ZoneId.of("America/New_York"));
LocalDateTime time5 = LocalDateTime.now();
getZongTime(time5, ZoneId.of("GMT+8"), ZoneId.of("America/New_York"));
}
可以看到对应输出时间: