ZetCode

Java ZoneOffsetTransition Class

Last modified: April 16, 2025

The java.time.zone.ZoneOffsetTransition class represents a transition between two offsets in a timezone. It models the moment when a timezone changes its standard offset or daylight saving rules.

ZoneOffsetTransition is immutable and thread-safe. It is used internally by the Java time API to handle timezone transitions. The class provides information about the transition instant and offset changes.

ZoneOffsetTransition Class Overview

ZoneOffsetTransition provides methods to examine timezone transitions. Key operations include getting transition instant, offsets, and duration. The class helps handle daylight saving time changes and other offset adjustments.

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);
}

The code above shows key methods provided by ZoneOffsetTransition. These methods allow examining timezone transitions in detail. The class helps understand how offsets change at specific moments in time.

Creating ZoneOffsetTransition Objects

ZoneOffsetTransition objects are typically obtained from ZoneRules. However, they can also be created directly for specific transitions. This example shows both approaches.

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);
    }
}

This example demonstrates two ways to create ZoneOffsetTransition objects. The first creates a transition manually, while the second retrieves one from timezone rules. Both represent the same daylight saving time transition.

Examining Transition Properties

ZoneOffsetTransition provides methods to examine transition details. These include the instant of transition, offsets before and after, and transition type.

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());
    }
}

This example shows how to examine properties of a timezone transition. The output reveals details about the fall daylight saving time change in New York. The duration shows the 1-hour difference between offsets.

Checking Valid Offsets

The isValidOffset method checks if a specific offset was valid at the transition point. This helps determine which local times were valid during transitions.

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));
    }
}

This example checks which offsets were valid during a daylight saving time transition. The method returns true only for offsets that were valid at the exact transition moment. This helps handle ambiguous times during transitions.

Handling Gap Transitions

Gap transitions occur when clocks move forward, creating a period of local time that doesn't exist. The isGap method identifies these transitions.

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");
        }
    }
}

This example demonstrates how to detect and handle gap transitions. During daylight saving time start, local time jumps forward, creating a gap. The example shows the exact moment when this occurs in New York timezone.

Handling Overlap Transitions

Overlap transitions occur when clocks move backward, creating a period of local time that occurs twice. The isOverlap method identifies these.

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");
        }
    }
}

This example shows how to detect and handle overlap transitions. During daylight saving time end, local time moves back, creating an overlap. The example shows this transition in New York timezone.

Comparing Transitions

ZoneOffsetTransition implements Comparable, allowing transitions to be sorted chronologically. The comparison is based on the transition instant.

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);
    }
}

This example demonstrates comparing and sorting ZoneOffsetTransition objects. The transitions are first displayed in original order, then shuffled, and finally sorted chronologically. The comparison uses the transition instant.

Source

Java ZoneOffsetTransition Class Documentation

In this article, we've covered the essential methods and features of the Java ZoneOffsetTransition class. Understanding these concepts is crucial for accurate timezone handling in Java applications.

Author

My name is Jan Bodnar, and I am a dedicated programmer with many years of experience in the field. I began writing programming articles in 2007 and have since authored over 1,400 articles and eight e-books. With more than eight years of teaching experience, I am committed to sharing my knowledge and helping others master programming concepts.

List all Java tutorials.