ZetCode

Java ZoneOffsetTransition 类

最后修改时间:2025 年 4 月 16 日

java.time.zone.ZoneOffsetTransition 类表示时区中两个偏移量之间的转换。 它模拟了时区更改其标准偏移量或夏令时规则的时刻。

ZoneOffsetTransition 是不可变的且线程安全的。 它由 Java 时间 API 内部使用来处理时区转换。 该类提供有关转换时刻和偏移量更改的信息。

ZoneOffsetTransition 类概述

ZoneOffsetTransition 提供了检查时区转换的方法。 关键操作包括获取转换时刻、偏移量和持续时间。 该类有助于处理夏令时更改和其他偏移量调整。

public final class ZoneOffsetTransition implements Comparable<ZoneOffsetTransition>, Serializable {
    public static ZoneOffsetTransition of(LocalDateTime transition, ZoneOffset before, ZoneOffset after);
    public Instant getInstant();
    public LocalDateTime getDateTimeBefore();
    public LocalDateTime getDateTimeAfter();
    public ZoneOffset getOffsetBefore();
    public ZoneOffset getOffsetAfter();
    public Duration getDuration();
    public boolean isGap();
    public boolean isOverlap();
    public boolean isValidOffset(ZoneOffset offset);
    public int compareTo(ZoneOffsetTransition transition);
}

上面的代码显示了 ZoneOffsetTransition 提供的关键方法。 这些方法允许详细检查时区转换。 该类有助于理解偏移量在特定时刻的变化方式。

创建 ZoneOffsetTransition 对象

ZoneOffsetTransition 对象通常从 ZoneRules 获取。 但是,也可以直接为特定转换创建它们。 此示例展示了这两种方法。

Main.java
package com.zetcode;

import java.time.*;
import java.time.zone.*;

public class Main {

    public static void main(String[] args) {
        
        // Create transition directly
        ZoneOffsetTransition transition1 = ZoneOffsetTransition.of(
            LocalDateTime.of(2025, 3, 9, 2, 0),
            ZoneOffset.ofHours(-5),
            ZoneOffset.ofHours(-4)
        );
        System.out.println("Created transition: " + transition1);
        
        // Get transitions from ZoneRules
        ZoneRules rules = ZoneId.of("America/New_York").getRules();
        ZoneOffsetTransition transition2 = rules.getTransition(
            LocalDateTime.of(2025, 3, 9, 2, 0)
        );
        System.out.println("From ZoneRules: " + transition2);
    }
}

此示例演示了两种创建 ZoneOffsetTransition 对象的方法。 第一种是手动创建转换,而第二种是从时区规则中检索一个。 两者都表示相同的夏令时转换。

检查转换属性

ZoneOffsetTransition 提供了检查转换详细信息的方法。 这些包括转换时刻、之前的偏移量和之后的偏移量以及转换类型。

Main.java
package com.zetcode;

import java.time.*;
import java.time.zone.*;

public class Main {

    public static void main(String[] args) {
        
        ZoneRules rules = ZoneId.of("America/New_York").getRules();
        ZoneOffsetTransition transition = rules.getTransition(
            LocalDateTime.of(2025, 11, 2, 2, 0)
        );
        
        System.out.println("Transition instant: " + transition.getInstant());
        System.out.println("Offset before: " + transition.getOffsetBefore());
        System.out.println("Offset after: " + transition.getOffsetAfter());
        System.out.println("Duration: " + transition.getDuration());
        System.out.println("Is gap: " + transition.isGap());
        System.out.println("Is overlap: " + transition.isOverlap());
    }
}

此示例展示了如何检查时区转换的属性。 输出揭示了关于纽约夏令时转换的详细信息。 持续时间显示了偏移量之间的 1 小时差异。

检查有效偏移量

isValidOffset 方法检查特定的偏移量在转换点是否有效。 这有助于确定在转换期间哪些本地时间有效。

Main.java
package com.zetcode;

import java.time.*;
import java.time.zone.*;

public class Main {

    public static void main(String[] args) {
        
        ZoneRules rules = ZoneId.of("America/New_York").getRules();
        ZoneOffsetTransition transition = rules.getTransition(
            LocalDateTime.of(2025, 3, 8, 2, 0)
        );
        
        ZoneOffset before = transition.getOffsetBefore();
        ZoneOffset after = transition.getOffsetAfter();
        
        System.out.println("Is before offset valid? " + 
            transition.isValidOffset(before));
        System.out.println("Is after offset valid? " + 
            transition.isValidOffset(after));
        System.out.println("Is UTC offset valid? " + 
            transition.isValidOffset(ZoneOffset.UTC));
    }
}

此示例检查在夏令时转换期间哪些偏移量有效。 该方法仅对在确切转换时刻有效的偏移量返回 true。 这有助于处理转换期间的歧义时间。

处理间隙转换

当时钟向前移动时,会发生间隙转换,从而创建一个不存在的本地时间段。 isGap 方法标识这些转换。

Main.java
package com.zetcode;

import java.time.*;
import java.time.zone.*;

public class Main {

    public static void main(String[] args) {
        
        ZoneRules rules = ZoneId.of("America/New_York").getRules();
        ZoneOffsetTransition transition = rules.getTransition(
            LocalDateTime.of(2025, 3, 9, 2, 0)
        );
        
        if (transition.isGap()) {
            System.out.println("This is a gap transition");
            System.out.println("Local time jumps from " + 
                transition.getDateTimeBefore() + " to " +
                transition.getDateTimeAfter());
        } else {
            System.out.println("This is not a gap transition");
        }
    }
}

此示例演示了如何检测和处理间隙转换。 在夏令时开始期间,本地时间向前跳跃,从而产生一个间隙。 该示例显示了纽约时区发生这种情况的确切时刻。

处理重叠转换

当钟表向后移动时,会发生重叠转换,从而创建一个本地时间段,该时间段出现两次。 isOverlap 方法标识这些。

Main.java
package com.zetcode;

import java.time.*;
import java.time.zone.*;

public class Main {

    public static void main(String[] args) {
        
        ZoneRules rules = ZoneId.of("America/New_York").getRules();
        ZoneOffsetTransition transition = rules.getTransition(
            LocalDateTime.of(2025, 11, 2, 2, 0)
        );
        
        if (transition.isOverlap()) {
            System.out.println("This is an overlap transition");
            System.out.println("Local time repeats from " + 
                transition.getDateTimeBefore() + " to " +
                transition.getDateTimeAfter());
        } else {
            System.out.println("This is not an overlap transition");
        }
    }
}

此示例展示了如何检测和处理重叠转换。 在夏令时结束期间,本地时间向后移动,从而产生重叠。 该示例显示了纽约时区的这种转换。

比较转换

ZoneOffsetTransition 实现了 Comparable 接口,允许按时间顺序对转换进行排序。 比较基于转换时刻。

Main.java
package com.zetcode;

import java.time.*;
import java.time.zone.*;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        
        ZoneRules rules = ZoneId.of("America/New_York").getRules();
        List<ZoneOffsetTransition> transitions = new ArrayList<>(
            rules.getTransitions().subList(0, 5)
        );
        
        System.out.println("Original order:");
        transitions.forEach(System.out::println);
        
        Collections.shuffle(transitions);
        System.out.println("\nShuffled order:");
        transitions.forEach(System.out::println);
        
        Collections.sort(transitions);
        System.out.println("\nSorted order:");
        transitions.forEach(System.out::println);
    }
}

此示例演示了比较和排序 ZoneOffsetTransition 对象。 转换首先以原始顺序显示,然后打乱,最后按时间顺序排序。 比较使用转换时刻。

来源

Java ZoneOffsetTransition 类文档

在本文中,我们介绍了 Java ZoneOffsetTransition 类的基本方法和特性。 了解这些概念对于在 Java 应用程序中进行准确的时区处理至关重要。

作者

我叫 Jan Bodnar,是一位经验丰富的程序员,在这个领域拥有多年的经验。 我从 2007 年开始撰写编程文章,至今已撰写了 1,400 多篇文章和 8 本电子书。 凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程