ZetCode

Java ValueRange 类

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

java.time.temporal.ValueRange 类表示时间字段的有效值范围。它存储最小值和最大值以及最小和最大的有效值。这在 Java Time API 中广泛用于字段验证。

ValueRange 是不可变的且线程安全的。它有助于验证时间字段的值,例如日-月或时-日。该类支持固定范围和可变范围,处理闰年和其他日历变化。

ValueRange 类概述

ValueRange 提供了检查值有效性和获取范围边界的方法。关键操作包括检查值是否在范围内以及查询最小值/最大值。该类处理包含范围检查和排除范围检查。

public final class ValueRange implements Serializable {
    public static ValueRange of(long min, long max);
    public static ValueRange of(long min, long maxSmallest, long maxLargest);
    public static ValueRange of(long min, long maxSmallest, long smallestMax, long largestMax);
    public boolean isValidValue(long value);
    public boolean isValidIntValue(long value);
    public long getMinimum();
    public long getMaximum();
    public long getLargestMinimum();
    public long getSmallestMaximum();
    public long checkValidValue(long value, TemporalField field);
    public int checkValidIntValue(long value, TemporalField field);
}

上面的代码显示了 ValueRange 提供的关键方法。这些方法允许创建范围并根据它们验证值。该类支持不同时间场景的固定范围和可变范围。

创建 ValueRange 对象

可以使用静态工厂方法创建 ValueRange 对象。最简单的形式仅采用最小值和最大值。更复杂的形式允许为诸如日-月之类的字段指定可变范围。

Main.java
package com.zetcode; 

import java.time.temporal.ValueRange;

public class Main {

    public static void main(String[] args) {
        
        // Fixed range (1-12 for months)
        ValueRange months = ValueRange.of(1, 12);
        System.out.println("Months range: " + months);
        
        // Variable range (1-28/29/30/31 for days)
        ValueRange days = ValueRange.of(1, 28, 31);
        System.out.println("Days range: " + days);
        
        // Full variable range (seconds in minute)
        ValueRange seconds = ValueRange.of(0, 59, 60);
        System.out.println("Seconds range: " + seconds);
        
        // Complex range (hours in day)
        ValueRange hours = ValueRange.of(0, 23, 24);
        System.out.println("Hours range: " + hours);
    }
}

此示例演示了创建 ValueRange 对象的不同方式。输出显示了具有其最小值和最大值的范围。请注意如何使用最小和最大最大值来表示可变范围。

检查值的有效性

ValueRange 的主要用途是验证值是否在可接受的范围内。 isValidValue 方法检查值是否在范围内。这对于输入验证非常有用。

Main.java
package com.zetcode; 

import java.time.temporal.ValueRange;

public class Main {

    public static void main(String[] args) {

        ValueRange monthRange = ValueRange.of(1, 12);
        
        // Check valid values
        System.out.println("Is 5 valid? " + monthRange.isValidValue(5));
        System.out.println("Is 12 valid? " + monthRange.isValidValue(12));
        
        // Check invalid values
        System.out.println("Is 0 valid? " + monthRange.isValidValue(0));
        System.out.println("Is 13 valid? " + monthRange.isValidValue(13));
        
        // Check edge cases
        System.out.println("Is Integer.MAX_VALUE valid? " + 
            monthRange.isValidValue(Integer.MAX_VALUE));
    }
}

此示例显示了如何针对范围验证值。该方法对于范围内的值返回 true,对于范围外的值返回 false。请注意,它可以正确处理大数字。

获取范围信息

ValueRange 提供了查询其边界的方法。这些方法包括获取最小值、最大值、最小最大值和最大最大值。这对于理解范围约束非常有用。

Main.java
package com.zetcode; 

import java.time.temporal.ValueRange;

public class Main {

    public static void main(String[] args) {

        ValueRange dayRange = ValueRange.of(1, 28, 31);
        
        // Get range information
        System.out.println("Minimum: " + dayRange.getMinimum());
        System.out.println("Maximum: " + dayRange.getMaximum());
        System.out.println("Smallest maximum: " + dayRange.getSmallestMaximum());
        System.out.println("Largest maximum: " + dayRange.getLargestMaximum());
        
        // Check if range is fixed
        System.out.println("Is fixed range? " + 
            (dayRange.getMinimum() == dayRange.getLargestMinimum() &&
             dayRange.getMaximum() == dayRange.getSmallestMaximum()));
    }
}

此示例演示了如何查询范围边界。对于可变范围,可能会返回不同的最大值。该示例还显示了如何检查范围是否固定(所有边界相等)。

使用异常验证值

ValueRange 可以验证值,并为无效值抛出异常。如果 checkValidValue 方法有效,则返回该值,否则抛出 DateTimeException。这对于严格的验证很有用。

Main.java
package com.zetcode; 

import java.time.temporal.ValueRange;
import java.time.DateTimeException;

public class Main {

    public static void main(String[] args) {

        ValueRange hourRange = ValueRange.of(0, 23);
        
        try {
            // Validate good value
            long validHour = hourRange.checkValidValue(15, null);
            System.out.println("Valid hour: " + validHour);
            
            // Validate bad value
            long invalidHour = hourRange.checkValidValue(25, null);
            System.out.println("This won't be printed");
            
        } catch (DateTimeException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

此示例显示了具有异常处理的严格验证。如果方法有效,则返回该值,否则为无效值抛出 DateTimeException。TemporalField 参数可用于更好的错误消息。

使用时间字段

ValueRange 通常与时间字段一起使用以验证值。许多时间字段提供其有效值范围。此示例显示了如何访问和使用这些范围。

Main.java
package com.zetcode; 

import java.time.Month;
import java.time.temporal.ChronoField;
import java.time.temporal.ValueRange;

public class Main {

    public static void main(String[] args) {

        // Get range for day-of-month
        ValueRange dayRange = ChronoField.DAY_OF_MONTH.range();
        System.out.println("Day of month range: " + dayRange);
        
        // Get range for specific month
        ValueRange febDayRange = ChronoField.DAY_OF_MONTH.rangeRefinedBy(
            Month.FEBRUARY);
        System.out.println("February days range: " + febDayRange);
        
        // Check validity for month days
        System.out.println("Is 31 valid for February? " + 
            febDayRange.isValidValue(31));
            
        // Get hour range
        ValueRange hourRange = ChronoField.HOUR_OF_DAY.range();
        System.out.println("Hour range: " + hourRange);
    }
}

此示例演示了时间字段如何提供其值范围。rangeRefinedBy 方法调整特定上下文(例如月份)的范围。这就是正确处理二月的日期范围的方式。

整数值验证

ValueRange 提供了用于整数验证的特殊方法。 isValidIntValuecheckValidIntValue 方法确保值适合 int。这对于需要 int 的 API 非常重要。

Main.java
package com.zetcode; 

import java.time.temporal.ValueRange;
import java.time.DateTimeException;

public class Main {

    public static void main(String[] args) {

        ValueRange smallRange = ValueRange.of(1, 100);
        ValueRange largeRange = ValueRange.of(1, Integer.MAX_VALUE + 1L);
        
        // Check int validity
        System.out.println("Is 50 valid int? " + smallRange.isValidIntValue(50));
        System.out.println("Is 2 billion valid int? " + 
            largeRange.isValidIntValue(2_000_000_000L));
            
        try {
            // Get valid int value
            int validInt = smallRange.checkValidIntValue(75, null);
            System.out.println("Valid int: " + validInt);
            
            // Try invalid long to int conversion
            int invalidInt = largeRange.checkValidIntValue(Integer.MAX_VALUE + 1L, null);
            System.out.println("This won't be printed");
            
        } catch (DateTimeException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

此示例显示了特定于整数的验证。这些方法确保值适合 int 范围(32 位有符号整数)。这可以防止从 long 转换为 int 时出现溢出问题。

来源

Java ValueRange 类文档

在本文中,我们介绍了 Java ValueRange 类的基本方法和功能。理解这些概念对于 Java 应用程序中的正确时间字段验证至关重要。

作者

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

列出所有Java教程