Skip to content

Windows and time zones

Every command reads a window, a span of time with a start and an end. This page covers the four ways to write one, why tsdive stores UTC only, and what to do with local timestamps.

Four ways to write a window

A window is ISO 8601 text. Both ends are included.

form example reads
START/END 2024-03-30T20:00:00Z/2024-03-31T01:00:00Z 20:00 to 01:00 UTC
START/DURATION 2024-03-30T20:00:00Z/PT5H the same five hours
DURATION/END PT5H/2024-03-31T01:00:00Z the same five hours
a date 2024-03-31 the whole UTC day, 00:00 to 00:00 the next day

A duration counts days, hours, minutes and seconds: PT5H, P2DT6H, PT90M. Months and years are refused, because their length varies. The same five hours, written two ways:

$ tsdive profile data/demo/fic101_demo.parquet --window 2024-03-30T20:00:00Z/PT5H
demo:FIC101.PV  FIC-101 flow
coverage 0.867   GOOD 262/262   censored no   gaps 1

window    2024-03-30 20:00:00Z -> 2024-03-31 01:00:00Z  (5 h)
[22 more lines not shown]
$ tsdive profile data/demo/fic101_demo.parquet --window PT5H/2024-03-31T01:00:00Z
demo:FIC101.PV  FIC-101 flow
coverage 0.867   GOOD 262/262   censored no   gaps 1

window    2024-03-30 20:00:00Z -> 2024-03-31 01:00:00Z  (5 h)
[22 more lines not shown]

Every bound carries its offset

A bound needs Z or an offset such as +02:00. tsdive converts an offset to UTC and prints UTC. A bound without one is refused, because tsdive cannot tell which instant it names:

$ tsdive profile data/demo/fic101_demo.parquet --window 2024-03-30T20:00:00/PT5H
error: window START is naive (2024-03-30 20:00:00); append 'Z' or '+00:00' - tsdive stores UTC only

The same window with a Berlin offset reads 19:00 to 00:00 UTC:

$ tsdive profile data/demo/fic101_demo.parquet --window 2024-03-30T20:00:00+01:00/PT5H
demo:FIC101.PV  FIC-101 flow
coverage 0.667   GOOD 202/202   censored no   gaps 2

window    2024-03-30 19:00:00Z -> 2024-03-31 00:00:00Z  (5 h)
[23 more lines not shown]

Local time in exports

Historian exports often write local time with no offset, such as 02/03/2026 08:00. That is a naive timestamp. tsdive ingest --tz Europe/Berlin states the zone it was written in, and ingest stores UTC. tsdive never assumes UTC for you.

Two more facts decide how an export's dates read:

  • A date such as 02/03/2026 is 2 March day first and 3 February month first. Ingest refuses it until you pass --dayfirst, or --timestamp-format with a strptime format such as %d/%m/%Y %H:%M.
  • In autumn a local hour repeats when the clocks go back. Ingest places its first pass at the summer offset and its second at the winter one, by row order. An export that holds the hour once, or out of time order, raises SchemaError.
  • In spring one local hour does not exist, and a time in it raises SchemaError. Export the stretch around either change with UTC offsets.

DST inside a window

profile --tz names zones whose clock changes inside the window the report should list. The demo window holds the change in Europe/London at 01:00 UTC on 31 March 2024. It changes nothing in the data, because the archive is in UTC. It tells you that a shift report in local time has an hour less that night:

$ tsdive profile data/demo/fic101_demo.parquet --tz Europe/London
demo:FIC101.PV  FIC-101 flow
coverage 0.933   GOOD 561/562   censored yes   gaps 1

window    2024-03-30 20:00:00Z -> 2024-03-31 06:00:00Z  (10 h)
contract  TIME_WEIGHTED  RECORDED  NONE  stepped no  digest d59d433d9c62
units     m3/h -> cubic meters per hour

Coverage
  coverage 0.933   valid 0.998   gaps 1   data-loss gaps 1   longest 40 min
  2024-03-30 23:00:00Z -> 23:40:00Z   40 min   unknown (no rule matched)

Quality
  GOOD 561   UNCERTAIN 1   BAD 0
  unmapped codes, treated UNCERTAIN: SENSOR DRIFT

Range
  clipped 0.0516   censored yes

Timestamps
  audited 562   duplicates 0   non-monotonic 0
  DST (Europe/London) 2024-03-31 01:00:00Z  +0h -> +1h

Values  GOOD n=561
  min 60.86   p05 61.20   median 62.32   p95 100.0   max 100.0
[4 more lines not shown]

What to do

  • Write windows with Z, or with the offset of the clock you read them from.
  • Ingest local exports with --tz, and with --dayfirst when the dates are day first.
  • Convert the UTC times a report prints before you look them up on a local trend.