Java 时区设置

在Java中,时区设置可以通过TimeZone类或ZoneId类(Java 8及以上版本)实现。以下是一些常见方法:

设置默认时区

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
// 或使用Java 8的ZoneId
System.setProperty("user.timezone", "Asia/Shanghai");

在日期时间API中指定时区

// 使用ZonedDateTime(Java 8+)
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));

// 使用SimpleDateFormat
SimpleDateFormat sdf = newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));

数据库连接时区设置

数据库连接的时区设置通常通过JDBC URL参数实现,不同数据库的配置方式略有差异。

MySQL时区配置

String url = "jdbc:mysql://localhost:3306/db?useSSL=false&serverTimezone=Asia/Shanghai";

PostgreSQL时区配置

String url = "jdbc:postgresql://localhost:5432/db?options=-c%20timezone=Asia/Shanghai";

Oracle时区配置

String url = "jdbc:oracle:thin:@localhost:1521:ORCL?oracle.jdbc.timezoneAsRegion=false";
// 或在连接后执行SQL
connection.createStatement().execute("ALTER SESSION SET TIME_ZONE='Asia/Shanghai'");

时区问题最佳实践

确保应用服务器、数据库和客户端的时区设置一致。推荐使用UTC时间存储在数据库中,在应用层根据需要进行转换。

存储UTC时间示例

Instant now = Instant.now(); // 获取UTC时间
PreparedStatement stmt = connection.prepareStatement("INSERT INTO table(time_col) VALUES(?)");
stmt.setObject(1, now);

从数据库读取时区转换

ZonedDateTime zdt = resultSet.getObject("time_col", Instant.class)
                           .atZone(ZoneId.of("Asia/Shanghai"));

常见问题解决

数据库连接出现时区错误时,检查以下配置:

  • 数据库服务器的默认时区设置
  • JDBC连接字符串中的时区参数
  • Java应用的默认时区设置
  • ORM框架(如Hibernate)的时区配置

对于Spring Boot应用,可以在application.properties中配置:

spring.jpa.properties.hibernate.jdbc.time_zone=Asia/Shanghai
spring.datasource.url=jdbc:mysql://localhost:3306/db?serverTimezone=Asia/Shanghai

更多推荐