本文目录导读:

我来详细说明Java时区设置的实操案例,涵盖常见场景和最佳实践。
获取和设置JVM默认时区
import java.util.TimeZone;
public class TimeZoneDemo {
public static void main(String[] args) {
// 1. 获取当前默认时区
TimeZone defaultTimeZone = TimeZone.getDefault();
System.out.println("默认时区ID: " + defaultTimeZone.getID());
System.out.println("默认时区显示名称: " + defaultTimeZone.getDisplayName());
// 2. 设置默认时区(影响整个JVM)
TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));
System.out.println("修改后时区: " + TimeZone.getDefault().getID());
// 3. 获取所有可用时区
String[] timeZoneIds = TimeZone.getAvailableIDs();
System.out.println("可用时区数量: " + timeZoneIds.length);
// 4. 获取特定时区
TimeZone beijingZone = TimeZone.getTimeZone("Asia/Shanghai");
System.out.println("北京时区偏移量(小时): " +
beijingZone.getRawOffset() / (3600 * 1000));
}
}
日期转换与格式化案例
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class DateTimeConversionDemo {
public static void main(String[] args) throws Exception {
// 场景:将中国时间转换为纽约时间
// 1. 创建中国时区的日期
TimeZone chinaZone = TimeZone.getTimeZone("Asia/Shanghai");
Calendar chinaCal = Calendar.getInstance(chinaZone);
chinaCal.set(2024, Calendar.NOVEMBER, 15, 10, 30, 0); // 2024-11-15 10:30
// 2. 设置DateFormat并显示
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 显示中国时间
sdf.setTimeZone(chinaZone);
System.out.println("北京时间: " + sdf.format(chinaCal.getTime()));
// 3. 转换为纽约时间
TimeZone newYorkZone = TimeZone.getTimeZone("America/New_York");
sdf.setTimeZone(newYorkZone);
System.out.println("纽约时间: " + sdf.format(chinaCal.getTime()));
// 4. 显示UTC时间
TimeZone utcZone = TimeZone.getTimeZone("UTC");
sdf.setTimeZone(utcZone);
System.out.println("UTC时间: " + sdf.format(chinaCal.getTime()));
}
}
使用Java 8+新日期API(推荐)
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.zone.ZoneRulesException;
public class Java8DateTimeDemo {
public static void main(String[] args) {
// 1. 获取当前时间在不同时区
ZonedDateTime now = ZonedDateTime.now();
System.out.println("当前系统时间: " + now);
// 2. 指定时区查看时间
ZonedDateTime beijingNow = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime newYorkNow = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println("北京时间: " + beijingNow);
System.out.println("纽约时间: " + newYorkNow);
// 3. 时区转换示例
ZonedDateTime meetingTime = ZonedDateTime.of(
2024, 11, 15, 14, 0, 0, 0,
ZoneId.of("Asia/Shanghai")
);
// 转换为其他时区
ZonedDateTime londonTime = meetingTime.withZoneSameInstant(
ZoneId.of("Europe/London")
);
ZonedDateTime tokyoTime = meetingTime.withZoneSameInstant(
ZoneId.of("Asia/Tokyo")
);
System.out.println("\n会议时间:");
System.out.println("北京: " + meetingTime.format(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
System.out.println("伦敦: " + londonTime.format(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
System.out.println("东京: " + tokyoTime.format(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));
// 4. 获取UTC时间戳
Instant instant = Instant.now();
System.out.println("\nUTC时间戳: " + instant);
System.out.println("UTC时间: " + instant.atZone(ZoneOffset.UTC));
// 5. 处理夏令时
try {
ZoneId usEastern = ZoneId.of("America/New_York");
System.out.println("\n纽约时区规则:");
System.out.println("当前是否有夏令时: " +
usEastern.getRules().isDaylightSavings(Instant.now()));
} catch (ZoneRulesException e) {
System.out.println("时区规则异常: " + e.getMessage());
}
}
}
Web应用时区设置(Spring Boot示例)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.PostConstruct;
import java.util.TimeZone;
@Configuration
public class TimeZoneConfig implements WebMvcConfigurer {
@PostConstruct
public void init() {
// 设置应用默认时区为中国时区
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
System.out.println("应用默认时区设置为: Asia/Shanghai");
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
return builder -> {
// JSON序列化时使用指定时区
builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
builder.dateFormat(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
};
}
}
数据库时区处理
import java.sql.*;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class DatabaseTimeZoneDemo {
public static void main(String[] args) throws SQLException {
// 1. 数据库连接设置
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai";
Properties props = new Properties();
props.setProperty("user", "root");
props.setProperty("password", "password");
// 2. 读取数据库时间
try (Connection conn = DriverManager.getConnection(url, props)) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT created_at FROM users WHERE id = 1");
if (rs.next()) {
// 获取数据库时间(直接获取为LocalDateTime)
LocalDateTime dbTime = rs.getObject("created_at", LocalDateTime.class);
// 转换为不同时区
ZonedDateTime chinaTime = dbTime.atZone(ZoneId.of("Asia/Shanghai"));
ZonedDateTime utcTime = chinaTime.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println("数据库时间: " + dbTime);
System.out.println("中国时间: " + chinaTime);
System.out.println("UTC时间: " + utcTime);
}
}
}
}
实用工具类
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
public class TimeZoneUtil {
/**
* 获取指定时区的当前时间
*/
public static String getCurrentTimeInTimezone(String timezoneId) {
ZonedDateTime now = ZonedDateTime.now(ZoneId.of(timezoneId));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return now.format(formatter);
}
/**
* 在不同时区间转换时间
*/
public static String convertTimezone(
String dateTime,
String fromTimezone,
String toTimezone,
String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime localDateTime = LocalDateTime.parse(dateTime, formatter);
ZonedDateTime fromZoned = localDateTime.atZone(ZoneId.of(fromTimezone));
ZonedDateTime toZoned = fromZoned.withZoneSameInstant(ZoneId.of(toTimezone));
return toZoned.format(formatter);
}
/**
* 检查时区是否有效
*/
public static boolean isValidTimezone(String timezoneId) {
try {
ZoneId.of(timezoneId);
return true;
} catch (Exception e) {
return false;
}
}
// 使用示例
public static void main(String[] args) {
// 1. 获取当前上海时间
System.out.println("当前上海时间: " +
getCurrentTimeInTimezone("Asia/Shanghai"));
// 2. 时区转换
String result = convertTimezone(
"2024-11-15 14:30:00",
"Asia/Shanghai",
"America/New_York",
"yyyy-MM-dd HH:mm:ss"
);
System.out.println("转换结果: " + result);
// 3. 验证时区
System.out.println("Asia/Shanghai有效: " + isValidTimezone("Asia/Shanghai"));
System.out.println("Invalid/Zone有效: " + isValidTimezone("Invalid/Zone"));
}
}
常见问题处理
public class TimeZoneCommonIssues {
public static void main(String[] args) {
// 1. 处理无效的时区ID
try {
ZoneId zoneId = ZoneId.of("China/Beijing");
} catch (Exception e) {
System.out.println("错误时区ID: " + e.getMessage());
// 使用正确的ID
ZoneId correctZone = ZoneId.of("Asia/Shanghai");
System.out.println("正确的时区: " + correctZone);
}
// 2. 推荐使用的时区列表
String[] recommendedTimezones = {
"Asia/Shanghai", // 中国标准时间
"America/New_York", // 美国东部时间
"America/Los_Angeles", // 美国西部时间
"Europe/London", // 英国时间
"Europe/Paris", // 欧洲中部时间
"Asia/Tokyo", // 日本时间
"Asia/Singapore", // 新加坡时间
"UTC" // 协调世界时
};
}
}
最佳实践建议
- 优先使用Java 8+的java.time包,避免使用旧的Date和Calendar
- 存储时间使用UTC,展示时再进行时区转换
- 避免使用缩写时区(如"PST"),使用地区格式(如"America/Los_Angeles")
- 在应用入口处统一设置时区,特别是在Web应用中
- 使用配置文件管理时区设置,便于环境切换
这些案例涵盖了日常开发中常见的时区处理场景,可以根据实际需求调整使用。