常用的时区转换有如下几种方式
方式一
转换原理
通过DateFormat 的format方法
代码示例
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class TimeZoneUtil {
public static void main(String[] args) throws ParseException {
//要转换的字符串时间
String sourceDateStr = "2023-04-02 11:00:00";
//源时区
String sourceTimeZoneCode = "Europe/Amsterdam";
//目标时区
String targetTimeZoneCode = "Asia/Shanghai";
//转换时区
convertTimezone(sourceDateStr,sourceTimeZoneCode,targetTimeZoneCode);
}
//转换时区
private static void convertTimezone(String sourceDateStr,String sourceTimeZoneCode,
String targetTimeZoneCode) throws ParseException {
//获取源时区的DateFormat
DateFormat sourceDateFormat = getDateFormat("yyyy-MM-dd HH:mm:ss", sourceTimeZoneCode);
//获取目标时区的DateFormat
DateFormat targetDateFormat = getDateFormat("yyyy-MM-dd HH:mm:ss", targetTimeZoneCode);
//设置要转换的时间(时区为源时区)
Date sourceDate = sourceDateFormat.parse(sourceDateStr);
//通过format方法转为目标时区
String targetDateStr = targetDateFormat.format(sourceDate);
System.out.println("转换后:" + targetDateStr);
}
//获取对应时区的DateFormat
public static DateFormat getDateFormat(String pattern, String timeZoneCode){
DateFormat sdf = new SimpleDateFormat(pattern);
TimeZone timeZone = TimeZone.getTimeZone(timeZoneCode);//根据时区code获取时区对象
sdf.setTimeZone(timeZone);//设置时区
return sdf;
}
}
扩展
1 获取系统时区(也叫本地时区)
示例值:“Europe/Amsterdam”、 “Asia/Shanghai”
String sysZoneId = TimeZone.getDefault().getID();
方式二
转换原理
通过 ZonedDateTime.ofInstant方法
代码示例
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.TimeZone;
public class TimeZoneUtil2 {
public static void main(String[] args) throws ParseException {
//要转换的字符串时间
String sourceDateStr = "2023-04-02 11:00:00";
//源时区
String sourceTimeZoneCode = "Europe/Amsterdam";
//目标时区
String targetTimeZoneCode = "Asia/Shanghai";
//转换时区
convertTimezone(sourceDateStr,sourceTimeZoneCode,targetTimeZoneCode);
}
//转换时区
private static void convertTimezone(String sourceDateStr,String sourceTimeZoneCode,
String targetTimeZoneCode) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//获取源时区的DateFormat
DateFormat sourceDateFormat = getDateFormat("yyyy-MM-dd HH:mm:ss", sourceTimeZoneCode);
//设置要转换的时间(时区为源时区)
Date sourceDate = sourceDateFormat.parse(sourceDateStr);
//转换
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(sourceDate.toInstant(),
TimeZone.getTimeZone(targetTimeZoneCode).toZoneId());
//ZonedDateTime转Date
Instant instant = zonedDateTime.toInstant();
Date date = Date.from(instant);
System.out.println("转换后:" + sdf.format(date));
}
public static DateFormat getDateFormat(String pattern, String timeZoneCode){
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
TimeZone timeZone = TimeZone.getTimeZone(timeZoneCode);//根据时区code获取时区对象
sdf.setTimeZone(timeZone);//设置时区
return sdf;
}
}
方式三
转换原理
通过时区偏移量转换
时区偏移量 ZoneOffset
每一个时区间隔是一个小时,所以偏移量就是60*60=3600,换做毫秒就是3600000
比如:
东一区跟0时区相差1小时,它的偏移量就是36000001=3600000
东八区跟0时区相差8小时,它的偏移量就是36000008=28800000
代码示例
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class TimeZoneUtil3 {
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//设置要转换的时间
String sourceTimeStr = "2023-04-02 11:00:00";
Date sourceDate = sdf.parse(sourceTimeStr);
//源时区
String sourceTimeZoneCode = "Europe/Amsterdam";
//目标时区
String targetTimeZoneCode = "Asia/Shanghai";
//转换时区
convertTimezone(sourceDate,sourceTimeZoneCode,targetTimeZoneCode);
}
//转换时区
private static void convertTimezone(Date sourceDate,String sourceTimeZoneCode,
String targetTimeZoneCode) {
//获取源时间毫秒值
long sourceTimeMillis = sourceDate.getTime();
//构造源时区Calendar
Calendar sourceCalendar = Calendar.getInstance();
sourceCalendar.setTimeInMillis(sourceTimeMillis);//设置时间
sourceCalendar.setTimeZone(TimeZone.getTimeZone(sourceTimeZoneCode));//设置源时区
//获取 源时区 到 UTC 的时区偏移量
int sourceZoneOffset = sourceCalendar.get(Calendar.ZONE_OFFSET);
//获取源时区的夏令时偏移量(如果做国际系统就要考虑这个)
int sourceDaylightOffset = sourceCalendar.get(Calendar.DST_OFFSET);
//构造目标时区Calendar
Calendar targetCalendar = Calendar.getInstance();
targetCalendar.setTimeInMillis(sourceTimeMillis);//设置时间
targetCalendar.setTimeZone(TimeZone.getTimeZone(targetTimeZoneCode));//设置目标时区
//获取 目标时区 到 UTC 的时区偏移量
int targetZoneOffset = targetCalendar.get(Calendar.ZONE_OFFSET);
//获取目标时区的夏令时偏移量(如果做国际系统就要考虑这个)
int targetDaylightOffset = targetCalendar.get(Calendar.DST_OFFSET);
//计算 源时区 和 目标时区 的偏移量差值
int offset = (targetZoneOffset + targetDaylightOffset) - (sourceZoneOffset + sourceDaylightOffset);
long targetTimeMillis = sourceTimeMillis + offset;
System.out.println("转换后:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date(targetTimeMillis)));
}
}