> For the complete documentation index, see [llms.txt](https://docs.butlr.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.butlr.io/integrations-api-third-party-sensors/reporting-api/time-zones-and-filling-gaps.md).

# Time Zones & Filling Gaps

## Time zones and windows

* **Sub-day windows** (`1m`–`1h`) start on UTC boundaries, e.g. `13:00:00Z`, `13:15:00Z`.
* **Daily windows** (`1d`) cover one calendar day in the **site's** local time zone.
* **Responses are always UTC.** `start` and `stop` are RFC 3339 UTC timestamps.

### What `timezone` does

`timezone` (an IANA name such as `America/New_York`, default UTC) affects two things only:

* **Date-only `start`/`stop`:** `"2026-09-14"` with `America/New_York` means `2026-09-14T04:00:00Z`. Timestamps with an offset are used as given.
* **`fill_gaps` at `1d`:** days are stepped in this time zone.

It does not change how stored data was aggregated.

### Daily timestamps

* **Recent data:** data from the last \~90 days stamps a day's `start` at local midnight expressed in UTC: `2026-09-14T04:00:00Z` for New York, `2026-09-13T15:00:00Z` for Tokyo.
* **Older data:** older data stamps it at `00:00:00Z` on the day's date.
* **Getting the day:** if `start` is `00:00:00Z`, use its UTC date. Otherwise, convert `start` to the site's time zone and use that date.
* **Daily `stop`:** always `start` + 24 hours, so on daylight-saving change days it does not match the next day's `start`.

## Filling gaps

By default, windows with no data are left out. With `"fill_gaps": true`, every window from `start` to `stop` appears for each entity in the response, and windows with no data contain only `start` and `stop`:

```json
{
  "data": {
    "spot_XXXX": [
      { "start": "2026-09-14T13:00:00Z", "stop": "2026-09-14T13:30:00Z", "occupancy_mean": 0.75 },
      { "start": "2026-09-14T13:30:00Z", "stop": "2026-09-14T14:00:00Z" },
      { "start": "2026-09-14T14:00:00Z", "stop": "2026-09-14T14:30:00Z", "occupancy_mean": 0.2 }
    ]
  }
}
```

* **Only entities that have data** are filled. An entity with no data in the range is still absent. If your UI needs every requested entity, add the missing keys yourself.
* **Alignment:** for sub-day intervals, the first window starts at the first UTC interval boundary at or after `start`. A `start` of `10:03` at `15m` gives a first window at `10:15`, and the partial window before it is not returned.
* **`1d`:** windows step one calendar day at a time from `start` exactly as given, in `timezone`. Stored days only match when their timestamps line up, which holds for the last \~90 days with a date-only `start` and `timezone` set to the site's time zone. For older daily data, leave `fill_gaps` off and fill missing days yourself, or the days that do have data come back empty.
* **Same-key measurements:** combining measurements with the same key keeps only one point per window (see [Combining measurements](/integrations-api-third-party-sensors/reporting-api.md#combining-measurements)).
* **Not supported with:** `interval: "1m"` (error `-5013`) or event measurements (error `-5015`).
* **Tighter range limits** apply; see [Query Limits](/integrations-api-third-party-sensors/reporting-api/query-limits.md).
