Class GranularZonedDateTime

java.lang.Object
org.apache.juneau.commons.time.GranularZonedDateTime

public class GranularZonedDateTime extends Object
A ZonedDateTime with precision information for granular time operations.

This class combines a ZonedDateTime with a ChronoField precision identifier, allowing for granular time operations such as rolling by specific time units.

The precision field indicates the granularity of the time value, which determines how the roll(int) method behaves. For example, a precision of ChronoField.YEAR means rolling by 1 will advance the year, while a precision of ChronoField.HOUR_OF_DAY means rolling by 1 will advance the hour.

ISO8601 Parsing:

The of(String) method can parse various ISO8601 timestamp formats:

  • Date formats: "2011", "2011-01", "2011-01-15"
  • DateTime formats: "2011-01-15T12", "2011-01-15T12:30", "2011-01-15T12:30:45"
  • With fractional seconds: "2011-01-15T12:30:45.123", "2011-01-15T12:30:45,123"
  • Time-only formats: "T12", "T12:30", "T12:30:45"
  • With timezone: "2011-01-15T12:30:45Z", "2011-01-15T12:30:45+05:30", "2011-01-15T12:30:45-05:30"

The precision is automatically determined from the input format. For example:

Example:

// Parse an ISO8601 timestamp with year precision GranularZonedDateTime gdt = GranularZonedDateTime.of("2011"); // Roll forward by one year gdt = gdt.roll(1); // Get the ZonedDateTime ZonedDateTime zdt = gdt.getZonedDateTime(); // Result: 2012-01-01T00:00:00 with system default timezone

// Parse a datetime with hour precision GranularZonedDateTime gdt2 = GranularZonedDateTime.of("2011-01-15T12Z"); // Roll forward by 2 hours gdt2 = gdt2.roll(ChronoField.HOUR_OF_DAY, 2); // Result: 2011-01-15T14:00:00Z

Thread Safety:

This class is immutable and thread-safe.

See Also:

  • Field Details

  • Constructor Details

  • Method Details

    • of

      public static GranularZonedDateTime of(Date date, ChronoField precision)
      Creates a GranularZonedDateTime from a Date with the specified precision.

      The date is converted to a ZonedDateTime using the system default timezone.

      Parameters:
      date - The date to convert. Must not be null (a null value throws NullPointerException).
      precision - The precision of the time value. Not validated — a null value is stored as-is and only surfaces later (e.g. roll(int) throws NullPointerException when precision is null).
      Returns:
      A new GranularZonedDateTime instance.
      Throws:
      NullPointerException - if date is null.
    • of

      public static GranularZonedDateTime of(Date date, ChronoField precision, ZoneId zoneId)
      Creates a GranularZonedDateTime from a Date with the specified precision and timezone.

      The date is converted to a ZonedDateTime using the specified timezone.

      Parameters:
      date - The date to convert. Must not be null (a null value throws NullPointerException).
      precision - The precision of the time value. Not validated — a null value is stored as-is and only surfaces later (e.g. roll(int) throws NullPointerException when precision is null).
      zoneId - The timezone to use. Must not be null (a null value throws NullPointerException).
      Returns:
      A new GranularZonedDateTime instance.
      Throws:
      NullPointerException - if date or zoneId is null.
    • of

      public static GranularZonedDateTime of(String value)
      Parses an ISO8601 timestamp string into a GranularZonedDateTime.

      This method parses various ISO8601 formats and automatically determines the precision based on the format. If no timezone is specified in the string, the system default timezone is used.

      Supported Formats:

      • Date: "2011", "2011-01", "2011-01-15"
      • DateTime: "2011-01-15T12", "2011-01-15T12:30", "2011-01-15T12:30:45"
      • With fractional seconds: "2011-01-15T12:30:45.123", "2011-01-15T12:30:45,123"
      • Time-only: "T12", "T12:30", "T12:30:45" (uses current date)
      • With timezone: "2011-01-15T12:30:45Z", "2011-01-15T12:30:45+05:30", "2011-01-15T12:30:45-05:30"

      Timezone Handling:

      • If the string contains a timezone (Z, +HH:mm, -HH:mm, etc.), that timezone is used.
      • If no timezone is specified, the system default timezone is used.
      • For time-only formats (starting with "T"), the current date is used with the specified or default timezone.

      Precision Detection:

      The precision is automatically determined from the format:

      Parameters:
      value - The ISO8601 timestamp string to parse.
      Returns:
      A new GranularZonedDateTime instance.
      Throws:
      IllegalArgumentException - if timestamp is null.
      DateTimeParseException - if the timestamp format is invalid.
    • of

      public static GranularZonedDateTime of(String value, Clock clock)
      Parses an ISO8601 timestamp string into a GranularZonedDateTime with a custom clock.

      This method is similar to of(String), but allows you to specify a custom Clock to use for obtaining the time zone and current time. This is useful for testing or when you need deterministic time behavior.

      The clock is used when:

      • No timezone is specified in the string - uses Clock.getZone()
      • Time-only formats (starting with "T") - uses the clock's instant to get the current date

      Example:

      // Parse with a fixed clock for deterministic testing var clock = Clock.fixed(Instant.parse("2000-01-01T12:00:00Z"), ZoneOffset.UTC); GranularZonedDateTime gdt = GranularZonedDateTime.of( "T12:30:45", clock ); // Result uses the clock's current date and timezone

      Parameters:
      value - The ISO8601 timestamp string to parse.
      clock - The clock to use for time zone and current time. If null, Clock.systemDefaultZone() is used.
      Returns:
      A new GranularZonedDateTime instance.
      Throws:
      IllegalArgumentException - if value is null.
      DateTimeParseException - if the timestamp format is invalid.
    • of

      public static GranularZonedDateTime of(String value, ZoneId defaultZoneId, Clock clock)
      Parses an ISO8601 timestamp string into a GranularZonedDateTime with a default timezone and custom clock.

      This method is similar to of(String), but allows you to specify both a default timezone and a custom Clock to use when no timezone is present in the timestamp string.

      If the timestamp string contains a timezone (Z, +HH:mm, -HH:mm, etc.), that timezone takes precedence over the defaultZoneId parameter. The defaultZoneId is only used when no timezone is specified in the string.

      The clock is used when:

      • No timezone is specified and defaultZoneId is null - uses Clock.getZone()
      • Time-only formats (starting with "T") - uses the clock's instant to get the current date

      Example:

      // Parse with default timezone and a fixed clock var clock = Clock.fixed(Instant.parse("2000-01-01T12:00:00Z"), ZoneOffset.UTC); GranularZonedDateTime gdt1 = GranularZonedDateTime.of( "2011-01-15T12:30:45", ZoneId.of("America/New_York"), clock ); // Result uses America/New_York timezone // Parse with timezone in string (defaultZoneId is ignored) GranularZonedDateTime gdt2 = GranularZonedDateTime.of( "2011-01-15T12:30:45Z", ZoneId.of("America/New_York"), clock ); // Result uses UTC (Z), not America/New_York

      Parameters:
      value - The ISO8601 timestamp string to parse.
      defaultZoneId - The default timezone to use if no timezone is specified in the string. If null, the clock's time zone is used.
      clock - The clock to use for time zone and current time. If null, Clock.systemDefaultZone() is used.
      Returns:
      A new GranularZonedDateTime instance.
      Throws:
      IllegalArgumentException - if value is null.
      DateTimeParseException - if the timestamp format is invalid.
    • of

      public static GranularZonedDateTime of(ZonedDateTime date, ChronoField precision)
      Creates a GranularZonedDateTime from a ZonedDateTime with the specified precision.

      This is the most direct way to create a GranularZonedDateTime when you already have a ZonedDateTime and want to specify its precision.

      Parameters:
      date - The ZonedDateTime value. Not validated — a null value is stored as-is.
      precision - The precision of the time value. Not validated — a null value is stored as-is.
      Neither argument is null-checked here; a null value only surfaces later (e.g. roll(int) or toString() throw NullPointerException when the corresponding field is null).
      Returns:
      A new GranularZonedDateTime instance.
    • copy

      Creates a copy of this object.
      Returns:
      A new GranularZonedDateTime with the same values.
    • getZonedDateTime

      Returns the ZonedDateTime value.
      Returns:
      The ZonedDateTime value.
    • getPrecision

      Returns the precision of this time value.

      The precision indicates the finest granularity of the time value, which determines how the value was parsed or created. For example:

      Returns:
      The precision of this time value.
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • roll

      public GranularZonedDateTime roll(ChronoField field, int amount)
      Rolls this time value by the specified amount using the specified field.

      This method creates a new GranularZonedDateTime by adding the specified amount to the specified field. The precision of the returned object remains the same as this object.

      Supported Fields:

      Example:

      // Create a datetime with hour precision GranularZonedDateTime gdt = GranularZonedDateTime.of("2011-01-15T12Z"); // Roll forward by 2 hours gdt = gdt.roll(ChronoField.HOUR_OF_DAY, 2); // Result: 2011-01-15T14:00:00Z (precision still HOUR_OF_DAY)

      Parameters:
      field - The field to roll by. Must be one of the supported fields listed above.
      amount - The amount to roll by. Positive values roll forward, negative values roll backward.
      Returns:
      A new GranularZonedDateTime with the rolled value.
      Throws:
      IllegalArgumentException - If the field is not supported.
    • roll

      public GranularZonedDateTime roll(int amount)
      Rolls this time value by the specified amount using the current precision.

      This is a convenience method that calls roll(ChronoField, int) using this object's precision field.

      Example:

      // Create a datetime with year precision GranularZonedDateTime gdt = GranularZonedDateTime.of("2011"); // Roll forward by 1 (using YEAR precision) gdt = gdt.roll(1); // Result: 2012-01-01T00:00:00 (precision still YEAR)

      Parameters:
      amount - The amount to roll by. Positive values roll forward, negative values roll backward.
      Returns:
      A new GranularZonedDateTime with the rolled value.