Java ZoneId 类
最后修改时间:2025 年 4 月 16 日
java.time.ZoneId
类表示时区标识符。 它用于识别在 Instant 和 LocalDateTime 之间进行转换的规则。 ZoneId 取代了旧的 TimeZone 类。
ZoneId
是不可变的且线程安全的。 它支持固定偏移量和地理区域。 该类提供对时区转换规则的访问。 所有时区规则均由 IANA 时区数据库定义。
ZoneId 类概述
ZoneId
提供了获取系统默认时区、从 ID 创建时区以及列出可用时区的方法。 主要操作包括在时间类型之间进行转换以及检查夏令时规则。 该类处理时区 ID 和固定偏移量。
public abstract class ZoneId implements Serializable { public static ZoneId systemDefault(); public static ZoneId of(String zoneId); public static Set<String> getAvailableZoneIds(); public abstract String getId(); public abstract ZoneRules getRules(); public boolean equals(Object obj); public static ZoneId from(TemporalAccessor temporal); }
上面的代码显示了 ZoneId
提供的关键方法。 这些方法允许创建、比较和检查时区。 该类通过 ZoneRules 类提供对详细时区规则的访问。
创建 ZoneId 对象
可以通过多种方式创建 ZoneId 对象。 最常用的方法是使用 of
获取特定时区,以及使用 systemDefault
获取 JVM 的当前时区。 该类还支持从字符串解析。
package com.zetcode; import java.time.ZoneId; public class Main { public static void main(String[] args) { // System default time zone ZoneId systemZone = ZoneId.systemDefault(); System.out.println("System default: " + systemZone); // Create from zone ID ZoneId parisZone = ZoneId.of("Europe/Paris"); System.out.println("Paris zone: " + parisZone); // Create from offset ZoneId offsetZone = ZoneId.of("+02:00"); System.out.println("Fixed offset: " + offsetZone); // Using ZoneId.SHORT_IDS ZoneId pstZone = ZoneId.of("PST", ZoneId.SHORT_IDS); System.out.println("PST zone: " + pstZone); } }
此示例演示了创建 ZoneId 对象的不同方法。 输出显示了各种时区表示形式。 请注意,像 "PST" 这样的短 ID 已弃用,应在新代码中避免使用。
列出可用时区
ZoneId 类提供对所有可用时区 ID 的访问。 这对于向用户显示时区选项或验证时区字符串非常有用。 这些 ID 遵循 IANA 时区数据库格式。
package com.zetcode; import java.time.ZoneId; import java.util.Set; public class Main { public static void main(String[] args) { // Get all available zone IDs Set<String> zoneIds = ZoneId.getAvailableZoneIds(); // Print first 10 zones zoneIds.stream() .sorted() .limit(10) .forEach(System.out::println); // Count total zones System.out.println("Total available zones: " + zoneIds.size()); // Check if a zone exists String zoneToCheck = "America/New_York"; System.out.println(zoneToCheck + " exists: " + zoneIds.contains(zoneToCheck)); } }
此示例显示了如何访问所有可用时区 ID。 该集合包含 600 多个条目。 这些 ID 按地区和城市排序,使其适合用户选择界面。
使用区域规则
每个 ZoneId 都提供对其 ZoneRules 的访问,其中包含有关时区行为的详细信息。 这包括偏移转换、夏令时规则和历史更改。
package com.zetcode; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.zone.ZoneRules; public class Main { public static void main(String[] args) { ZoneId zone = ZoneId.of("America/New_York"); ZoneRules rules = zone.getRules(); // Current standard offset ZoneOffset currentOffset = rules.getOffset(java.time.Instant.now()); System.out.println("Current offset: " + currentOffset); // Is daylight saving in effect? System.out.println("Is DST: " + rules.isDaylightSavings( java.time.Instant.now())); // Next transition System.out.println("Next transition: " + rules.nextTransition(java.time.Instant.now())); // Standard offset System.out.println("Standard offset: " + rules.getStandardOffset( java.time.Instant.now())); } }
此示例演示了如何访问详细的时区规则。 ZoneRules 对象提供有关特定时刻时区行为的信息。 这对于处理夏令时转换特别有用。
在时间类型之间转换
ZoneId 通常用于在 Instant 和 LocalDateTime 之间进行转换。 当处理机器和人类时间表示时,这些转换至关重要。
package com.zetcode; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; public class Main { public static void main(String[] args) { ZoneId zone = ZoneId.of("Europe/Berlin"); Instant now = Instant.now(); // Convert Instant to ZonedDateTime ZonedDateTime zoned = now.atZone(zone); System.out.println("In Berlin: " + zoned); // Convert LocalDateTime to ZonedDateTime LocalDateTime local = LocalDateTime.now(); ZonedDateTime zonedLocal = local.atZone(zone); System.out.println("Local in Berlin: " + zonedLocal); // Convert ZonedDateTime to Instant Instant back = zoned.toInstant(); System.out.println("Back to instant: " + back); // Convert between zones ZonedDateTime nyTime = zoned.withZoneSameInstant(ZoneId.of("America/New_York")); System.out.println("In New York: " + nyTime); } }
此示例显示了使用 ZoneId 在不同时间类型之间进行的转换。 atZone
方法将时区信息附加到 Instant 或 LocalDateTime。 区域之间的转换保留了同一时刻的时间。
处理夏令时
ZoneId 自动处理夏令时转换。 该类提供了检查 DST 是否生效以及计算适当偏移量的方法。 这确保了全年正确的计时计算。
package com.zetcode; import java.time.LocalDateTime; import java.time.Month; import java.time.ZoneId; import java.time.ZonedDateTime; public class Main { public static void main(String[] args) { ZoneId zone = ZoneId.of("America/New_York"); // Before DST transition (March 12, 2023 1:59 AM) LocalDateTime before = LocalDateTime.of(2023, Month.MARCH, 12, 1, 59); ZonedDateTime beforeZoned = before.atZone(zone); System.out.println("Before transition: " + beforeZoned); // After DST transition (March 12, 2023 3:00 AM) LocalDateTime after = LocalDateTime.of(2023, Month.MARCH, 12, 3, 0); ZonedDateTime afterZoned = after.atZone(zone); System.out.println("After transition: " + afterZoned); // Check DST in effect System.out.println("Is DST in July: " + zone.getRules().isDaylightSavings( LocalDateTime.of(2023, Month.JULY, 1, 0, 0).atZone(zone).toInstant())); } }
此示例演示了夏令时处理。 America/New_York 时区于 2023 年 3 月 12 日转换为 DST。 请注意时钟如何从凌晨 1:59 直接跳到凌晨 3:00,跳过了无效的小时。
使用固定偏移量
ZoneId 支持固定偏移量时区,这些时区不遵守夏令时。 当处理需要简单的基于偏移量的时区而无需区域规则的系统时,这些非常有用。
package com.zetcode; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; public class Main { public static void main(String[] args) { // Create fixed offset zone ZoneId fixedZone = ZoneId.of("+05:30"); System.out.println("Fixed zone: " + fixedZone); // Using ZoneOffset ZoneOffset offset = ZoneOffset.ofHoursMinutes(5, 30); ZoneId offsetZone = ZoneId.ofOffset("UTC", offset); System.out.println("Offset zone: " + offsetZone); // Convert with fixed offset LocalDateTime local = LocalDateTime.now(); ZonedDateTime zoned = local.atZone(offsetZone); System.out.println("With offset: " + zoned); // Check if fixed System.out.println("Is fixed offset: " + offsetZone.getRules().isFixedOffset()); } }
此示例显示了如何使用固定偏移量时区。 固定偏移量全年不变,使其比区域时区更简单但灵活性更低。 ZoneOffset 类提供其他特定于偏移量的功能。
来源
在本文中,我们介绍了 Java ZoneId 类的基本方法和功能。 了解这些概念对于在现代 Java 应用程序中进行准确的时区处理至关重要。
作者
列出所有Java教程。