ZetCode

Java ZoneRulesException 类

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

java.time.zone.ZoneRulesException 是一个运行时异常。它表示时区规则出现问题。当遇到无效的时区数据时,会发生此异常。

ZoneRulesException 扩展了 DateTimeException。它由 java.time.zone 包中的类抛出。常见原因包括缺少或损坏的时区数据文件。

ZoneRulesException 类概述

ZoneRulesException 标志着时区规则处理方面的问题。它有两个构造函数用于创建异常。该类提供了从 RuntimeException 继承的标准异常方法。

public class ZoneRulesException extends DateTimeException {
    public ZoneRulesException(String message);
    public ZoneRulesException(String message, Throwable cause);
}

上面的代码显示了 ZoneRulesException 的构造函数。第一个构造函数使用消息创建异常。第二个构造函数添加了导致异常的原因。这两个构造函数都是公共的。

基本 ZoneRulesException 示例

此示例演示了可能发生 ZoneRulesException 的简单情况。我们尝试使用无效的时区 ID 创建一个 ZoneId。

Main.java
package com.zetcode;

import java.time.ZoneId;

public class Main {

    public static void main(String[] args) {
        try {
            // Attempt to use invalid time-zone ID
            ZoneId zone = ZoneId.of("Invalid/TimeZone");
            System.out.println("Zone: " + zone);
        } catch (java.time.zone.ZoneRulesException e) {
            System.out.println("Caught ZoneRulesException: " + e.getMessage());
        }
    }
}

此代码尝试使用无效 ID 创建一个 ZoneId。当 ZoneId.of() 方法找不到指定时区的规则时,它会抛出 ZoneRulesException。异常被捕获并处理。

带有自定义消息的 ZoneRulesException

我们可以手动创建和抛出 ZoneRulesException。这在自定义代码中验证时区数据时非常有用。

Main.java
package com.zetcode;

import java.time.zone.ZoneRulesException;

public class Main {

    public static void main(String[] args) {
        try {
            validateTimeZone("Europe/Prague");
            validateTimeZone("Invalid/Zone");
        } catch (ZoneRulesException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

    private static void validateTimeZone(String zoneId) {
        if (zoneId.equals("Invalid/Zone")) {
            throw new ZoneRulesException("Custom error: Invalid time zone " + zoneId);
        }
        System.out.println("Valid time zone: " + zoneId);
    }
}

此示例显示手动验证时区 ID。当检测到无效时区时,我们抛出带有自定义消息的 ZoneRulesException。异常在 main 方法中被捕获。

带有原因的 ZoneRulesException

ZoneRulesException 可以包含导致异常的原因。当包装与时区处理相关的较低级别异常时,这很有用。

Main.java
package com.zetcode;

import java.time.zone.ZoneRulesException;

public class Main {

    public static void main(String[] args) {
        try {
            loadTimeZoneData();
        } catch (ZoneRulesException e) {
            System.out.println("Caught ZoneRulesException: " + e.getMessage());
            System.out.println("Cause: " + e.getCause().getClass().getName());
        }
    }

    private static void loadTimeZoneData() {
        try {
            // Simulate an error reading time-zone data
            throw new java.io.IOException("Failed to read time-zone data file");
        } catch (java.io.IOException e) {
            throw new ZoneRulesException("Time-zone data loading failed", e);
        }
    }
}

此示例演示了如何在 ZoneRulesException 中包装 IOException。原始异常成为原因。调用者可以访问高级消息和根本原因。

处理缺失的时区数据

当缺少时区数据时,经常会发生 ZoneRulesException。此示例展示了如何优雅地处理此类情况。

Main.java
package com.zetcode;

import java.time.ZoneId;
import java.time.zone.ZoneRulesException;

public class Main {

    public static void main(String[] args) {
        String[] zones = {"America/New_York", "Invalid/Zone", "Europe/London"};
        
        for (String zoneId : zones) {
            try {
                ZoneId zone = ZoneId.of(zoneId);
                System.out.println("Successfully loaded zone: " + zone);
            } catch (ZoneRulesException e) {
                System.out.println("Failed to load zone '" + zoneId + 
                    "': " + e.getMessage());
                // Fall back to system default time zone
                ZoneId defaultZone = ZoneId.systemDefault();
                System.out.println("Using default zone: " + defaultZone);
            }
        }
    }
}

此代码尝试加载多个时区。当发生 ZoneRulesException 时,它会回退到系统默认时区。当特定时区数据不可用时,此方法提供了优雅的降级。

ZoneRulesException in ZoneRulesProvider

在使用 ZoneRulesProvider 时,可能会发生 ZoneRulesException。此示例演示了自定义时区规则无效的情况。

Main.java
package com.zetcode;

import java.time.zone.ZoneRulesException;
import java.time.zone.ZoneRulesProvider;

public class Main {

    public static void main(String[] args) {
        try {
            // Attempt to register invalid zone rules
            ZoneRulesProvider provider = new InvalidZoneRulesProvider();
            ZoneRulesProvider.registerProvider(provider);
        } catch (ZoneRulesException e) {
            System.out.println("ZoneRulesException caught: " + e.getMessage());
            System.out.println("Could not register custom zone rules provider");
        }
    }
}

class InvalidZoneRulesProvider extends ZoneRulesProvider {
    @Override
    protected java.util.Set<String> provideZoneIds() {
        throw new ZoneRulesException("Invalid zone rules provided");
    }
    
    // Other required methods omitted for brevity
}

此示例显示了一个抛出 ZoneRulesException 的自定义 ZoneRulesProvider。当提供无效的时区规则时,会发生异常。main 方法适当地捕获和处理异常。

DateTimeFormatter 中的 ZoneRulesException

在日期时间解析期间,当时区信息无效时,可能会发生 ZoneRulesException。此示例演示了这种情况。

Main.java
package com.zetcode;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.zone.ZoneRulesException;

public class Main {

    public static void main(String[] args) {
        String[] dateStrings = {
            "2025-01-01T12:00:00Z[UTC]",
            "2025-01-01T12:00:00Z[Invalid/Zone]"
        };
        
        DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
        
        for (String dateString : dateStrings) {
            try {
                ZonedDateTime zdt = ZonedDateTime.parse(dateString, formatter);
                System.out.println("Parsed successfully: " + zdt);
            } catch (DateTimeParseException e) {
                System.out.println("Parse failed: " + e.getMessage());
            } catch (ZoneRulesException e) {
                System.out.println("Invalid zone rules: " + e.getMessage());
            }
        }
    }
}

此代码尝试解析带有时区信息的日期时间字符串。第二个字符串包含无效的时区 ID。解析器抛出 ZoneRulesException,该异常与解析错误分开捕获和处理。

ZoneRulesException in ZoneOffsetTransition

在使用时区转换时,可能会发生 ZoneRulesException。此示例显示了转换规则无效的情况。

Main.java
package com.zetcode;

import java.time.ZoneId;
import java.time.zone.ZoneRules;
import java.time.zone.ZoneRulesException;

public class Main {

    public static void main(String[] args) {
        try {
            ZoneId zone = ZoneId.of("Europe/Prague");
            ZoneRules rules = zone.getRules();
            
            // This might throw ZoneRulesException if transition rules are invalid
            rules.getTransitions().forEach(System.out::println);
            
        } catch (ZoneRulesException e) {
            System.out.println("Error processing zone rules: " + e.getMessage());
        }
    }
}

此示例检索时区的转换规则。如果规则无效或损坏,则可能抛出 ZoneRulesException。异常在 main 方法中捕获和处理。

来源

Java ZoneRulesException 类文档

在本文中,我们介绍了 Java 中的 ZoneRulesException 类。我们探讨了此异常发生的常见场景以及如何正确处理它。理解这些情况有助于构建强大的时区感知应用程序。

作者

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

列出所有Java教程