Package org.zkoss.zul

Class DateRange

java.lang.Object
org.zkoss.zul.DateRange
All Implemented Interfaces:
Serializable, Comparable<DateRange>

public final class DateRange extends Object implements Serializable, Comparable<DateRange>
An immutable value object representing a Date-based range, used as the value object of Daterangebox.

Either end may be null to denote an open-ended range:

  • begin == null && end == null — empty range.
  • begin == null && end != null — open start ("before end").
  • begin != null && end == null — open end ("after begin").
  • both non-null — closed range.

The class intentionally does not auto-swap when begin > end; the raw input is preserved so the UI layer can decide how to surface the inversion.

Instances are Serializable and Comparable: ordering compares begin first then end, treating null as the smallest value.

Since:
11.0.0
Author:
peaker
See Also:
  • Constructor Details

    • DateRange

      public DateRange(Date begin, Date end)
      Constructs a new range. Either begin or end may be null to denote an open-ended range.
      Parameters:
      begin - the begin date (inclusive), or null for open start
      end - the end date (inclusive), or null for open end
  • Method Details

    • of

      public static DateRange of(Date begin, Date end)
      Static factory equivalent to DateRange(Date, Date).
      Parameters:
      begin - the begin date (inclusive), or null
      end - the end date (inclusive), or null
      Returns:
      a new DateRange
    • getBegin

      public Date getBegin()
      Returns the begin date, or null if the range has an open start.
      Returns:
      the begin date (defensive copy), or null
    • getEnd

      public Date getEnd()
      Returns the end date, or null if the range has an open end.
      Returns:
      the end date (defensive copy), or null
    • isEmpty

      public boolean isEmpty()
      Returns:
      true if both ends are null.
    • isOpenStart

      public boolean isOpenStart()
      Returns:
      true if begin is null but end is not.
    • isOpenEnd

      public boolean isOpenEnd()
      Returns:
      true if end is null but begin is not.
    • isClosed

      public boolean isClosed()
      Returns:
      true if both ends are non-null.
    • contains

      public boolean contains(Date value)
      Tests whether the supplied date falls within this range. The comparison is null-safe and inclusive on both ends. null ends are treated as unbounded (negative or positive infinity respectively).
      Parameters:
      value - the date to test, may be null
      Returns:
      true if value is within the range
    • getDays

      public OptionalLong getDays()
      Returns the inclusive 24-hour-block count between begin and end. A range whose endpoints fall on the same UTC instant returns 1; each additional full 24 h adds 1.

      Wall-clock, not calendar-day, semantics. The result is derived from end - begin in milliseconds, divided by 24 h. A range like 2026-01-01 23:59 → 2026-01-02 00:01 spans two calendar dates but returns 1 because the wall-clock duration is only two minutes. Likewise a DST "spring forward" range whose endpoints both read 02:30 local time can return 0 because the underlying duration is 23 h. For zone-aware calendar-day counting use LocalDateRange.getDays() instead.

      Returns an empty OptionalLong when the range is not closed (either end is null). When the range is closed and inverted (end before begin) a non-positive value is wrapped in the optional — this class does not auto-swap. The optional return type is deliberate: it forces callers to acknowledge the "open-ended" case at compile time, replacing the previous Long.MIN_VALUE sentinel which collided with sub-24 h inverted ranges.

      Inverted-range semantics. The signed formula is diffMs >= 0 ? toDays(diffMs) + 1 : toDays(diffMs) - 1. The inclusive-count language only applies to forward ranges; for inverted ranges the returned value is a negative "signed inclusive count" (e.g. begin=Jan 5, end=Jan 4 → -2; begin=Jan 5 noon, end=Jan 5 morning → -1). Callers reasoning about magnitude should apply Math.abs(...); callers wanting only forward ranges should swap endpoints before calling, or check compareTo(...).

      Returns:
      the inclusive 24-h-block count for closed ranges (negative when inverted), or OptionalLong.empty() when either endpoint is null
    • overlaps

      public boolean overlaps(DateRange other)
      Tests whether this range overlaps the supplied range. null ends are treated as unbounded. An empty range never overlaps.
      Parameters:
      other - the other range
      Returns:
      true if the two ranges share at least one instant
    • equals

      public boolean equals(Object o)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Returns a debug representation in the form "yyyy-MM-dd ~ yyyy-MM-dd". The yyyy-MM-dd pattern is locale-insensitive and the zone is UTC, so the same range prints identically across JVMs and locales — this is meant for logs and diagnostics, not user-facing display. For zone-aware formatting use the DateRange value together with the consumer's own SimpleDateFormat/DateTimeFormatter.
      Overrides:
      toString in class Object
    • compareTo

      public int compareTo(DateRange o)
      Specified by:
      compareTo in interface Comparable<DateRange>