// 也可以使用"+8" 北京在东8区
public static final String BEIJING = "Asia/Shanghai";
// 芝加哥
public static final String CHICAGO = "America/Chicago";
public static final String NEWYORK = "America/New_York";
/**
* 时区转换
*/
private static ZonedDateTime convertTimezone(LocalDateTime time, ZoneId src, ZoneId dest) {
Objects.requireNonNull(dest);
ZonedDateTime z1 = null;
if (src == null) {
z1 = time.atZone(ZoneId.systemDefault());
} else {
z1 = time.atZone(src);
}
ZonedDateTime z2 = z1.withZoneSameInstant(dest);
long hours = Duration.between(z2.withEarlierOffsetAtOverlap(), z2.withLaterOffsetAtOverlap()).toHours();
z2 = z2.plusHours(hours);
return z2;
}
/**
* <p>
* 时区转换
* <p>
* 处理掉夏令时问题
*
* @param date 时间
* @param src 当前时间时区
* @param dest 转换的时间时区
* @return date
*/
public static LocalDateTime convertTimezoneToLocalDateTime(LocalDateTime date, ZoneId src, ZoneId dest) {
ZonedDateTime z2 = convertTimezone(date, src, dest);
return z2.toLocalDateTime();
}
public static void main(String[] args) {
// 芝加哥在当地时间 2021年03月14日,02:00:00 时钟向前调整 1 小时 变为 2021年03月14日,03:00:00,开始夏令时
// 夏令时结束
// 芝加哥在当地时间 2021年11月07日,02:00:00 时钟向后调整 1 小时 变为 2021年11月07日,01:00:00,结束夏令时
// 初始化一个芝加哥时间
ZonedDateTime atZone = LocalDateTime.of(2021, 11, 07, 02, 00, 00).atZone(ZoneId.of(CHICAGO));
//千万不要转date(跟服务器时区相关),获取跟指定时间会不一样,LocalDateTime获取的时间是一样的
LocalDateTime localTime = atZone.toLocalDateTime();
System.out.println(localTime);
LocalDateTime chinaTime = convertTimezoneToLocalDateTime(localTime, ZoneId.of(CHICAGO), ZoneId.of(BEIJING));
String date = chinaTime.format(DateTimeFormatter.ISO_DATE_TIME);
SimpleDateFormat format0 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date parseDate = DateUtil.parseDate(date, format0);
System.out.println(parseDate);
}