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教程。