# Class HealthInterval

java.lang.Object
com.codename1.health.HealthInterval

public final class HealthInterval extends Object

The bucket width of an `AggregateQuery` -- "per hour", "per calendar day", "per calendar month".

##### Fixed durations and calendar periods are not the same thing

A calendar day is 23 or 25 hours across a daylight-saving transition, and a month is 28 to 31 days. Bucketing by a fixed `86400000` therefore drifts against the dates a user sees in your UI, silently, twice a year. Both platforms model the distinction natively -- Health Connect splits `aggregateGroupByDuration` from `aggregateGroupByPeriod`, and HealthKit takes `DateComponents` -- so this API keeps it too.

Calendar-based intervals require an explicit `ZoneId`. Nothing here reads the JVM default, because a server-side default of UTC would put a user's evening walk into the wrong day.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `long`
  `bucketStart(long millis, long anchorMillis)`
  The start of the bucket that contains `millis`.
  `static HealthInterval`
  `calendarDays(int days, ZoneId zone)`
  Calendar days in `zone`, aligned to local midnight.
  `static HealthInterval`
  `calendarMonths(int months, ZoneId zone)`
  Calendar months in `zone`, aligned to local midnight on the first of the month.
  `static HealthInterval`
  `calendarWeeks(int weeks, ZoneId zone, int firstDayOfWeek)`
  Calendar weeks in `zone`, aligned to `firstDayOfWeek` (a `java.util.Calendar` day constant such as `Calendar.MONDAY`).
  `Duration`
  `getDuration()`
  This interval as a `Duration`, or null when it is calendar-based.
  `long`
  `getFixedMillis()`
  The fixed width in milliseconds, or 0 when `isCalendarBased()`.
  `ZoneId`
  `getZone()`
  The zone calendar boundaries are computed in, or null for a fixed-duration interval.
  `static HealthInterval`
  `hours(int hours)`
  A fixed number of hours.
  `boolean`
  `isCalendarBased()`
  `true` when this interval follows the calendar rather than a fixed number of milliseconds.
  `static HealthInterval`
  `millis(long millis)`
  A fixed number of milliseconds.
  `static HealthInterval`
  `minutes(int minutes)`
  A fixed number of minutes.
  `long`
  `nextBoundary(long bucketStartMillis)`
  The start of the bucket after the one starting at `bucketStartMillis`.
  `static HealthInterval`
  `of(Duration length)`
  An interval of `length`.
  `String`
  `toString()`
  Returns a string representation of the object.

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Method Details

  - ### millis

    public static HealthInterval millis(long millis)
    A fixed number of milliseconds.

  - ### minutes

    public static HealthInterval minutes(int minutes)
    A fixed number of minutes.

  - ### hours

    public static HealthInterval hours(int hours)
    A fixed number of hours.

  - ### calendarDays

    public static HealthInterval calendarDays(int days, ZoneId zone)
    Calendar days in `zone`, aligned to local midnight. Correct across daylight-saving transitions.

  - ### calendarWeeks

    public static HealthInterval calendarWeeks(int weeks, ZoneId zone, int firstDayOfWeek)
    Calendar weeks in `zone`, aligned to `firstDayOfWeek` (a `java.util.Calendar` day constant such as `Calendar.MONDAY`). The first day of the week is explicit because it differs by locale and silently guessing it shifts every bucket boundary.

  - ### calendarMonths

    public static HealthInterval calendarMonths(int months, ZoneId zone)
    Calendar months in `zone`, aligned to local midnight on the first of the month.

  - ### isCalendarBased

    public boolean isCalendarBased()
    `true` when this interval follows the calendar rather than a fixed number of milliseconds.

  - ### getFixedMillis

    public long getFixedMillis()
    The fixed width in milliseconds, or 0 when `isCalendarBased()`.

  - ### getZone

    public ZoneId getZone()

    The zone calendar boundaries are computed in, or null for a fixed-duration interval.

    A `ZoneId` rather than a `java.util.TimeZone`, and immutable, so it can be handed out as-is. The mutable type needed a caveat instead of an answer: an interval built from a `SimpleTimeZone` that was later reconfigured moved its bucket boundaries, putting the same samples in different days, and the compile target could not defend against it -- the CLDC 1.1 subset exposes no public `TimeZone.clone()`, and `getTimeZone(getID())` answers GMT for an unrecognised id, which would have silently discarded the rules of the very zone being protected.

  - ### getDuration

    public Duration getDuration()

    This interval as a `Duration`, or null when it is calendar-based.

    A calendar day is 23, 24 or 25 hours depending on the transition it spans, so a calendar interval has no fixed length and saying otherwise would be the drift this API takes an explicit zone to avoid.

  - ### of

    public static HealthInterval of(Duration length)
    An interval of `length`.

  - ### bucketStart

    public long bucketStart(long millis, long anchorMillis)
    The start of the bucket that contains `millis`. For a fixed interval this is anchored on `anchorMillis`; for a calendar interval it snaps to the local period boundary and `anchorMillis` is ignored.

  - ### nextBoundary

    public long nextBoundary(long bucketStartMillis)
    The start of the bucket after the one starting at `bucketStartMillis`. Bucket `n`'s exclusive end is bucket `n+1`'s inclusive start, so buckets tile with no gap and no overlap even when their widths differ.

  - ### toString

    public String toString()
    Description copied from class: `Object`
    Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + '@' + Integer.toHexString(hashCode())
    Overrides:
      `toString` in class `Object`