A time of day is when in its day something happened, read as a number so it can be charted, averaged and compared: the hour you woke, the time you went to bed, when you first ate. Datler stores no time of day of its own. It reads one off an instant already stored, the time an entry happened or an interval’s start or end, when the entry is read. So a sleep logged as one interval also gives its bedtime and its waketime as series, with nothing logged twice.

The frame

A clock reading is seconds from midnight of the day the entry counts for (clockOf in packages/core/src/clock.ts). An interval’s end and an entry’s own time fall within that day, from 0 up to 24 hours. An interval’s start can fall the evening before, and is then negative: a sleep from 23:30 to 07:00 counted for the morning reads its bedtime as −1800 and its waketime as 25200.

Measuring every instant from the midnight of its own day would make a 23:30 bedtime larger than a 00:30 one and put their mean at noon. Measured from the day the entry counts for, the later bedtime is the larger number, a mean of bedtimes lands where bedtimes are, and end minus start is the length by construction.

An open interval has no clock reading for either end, the same rule that keeps its length out of every total. An entry kept by its day alone, with no time (Whole day), has no clock reading of its own instant or of an interval’s ends; a moment kept by its day alone has no time of day either (momentSeconds is null): Any and Count read it, every other reduce leaves it out, it falls in no window of the day, and it answers the day’s first place.

Reading one

A Reading’s map of an instant (at, start or end) reads it as a time of day (Readings). Bedtime and Waketime in the Sleep module are derived trackables that read Main sleep’s start and end this way (Sleep), and Diet mapped to at and read by Min is the time of the first thing eaten each day. A trackable logged with no value, a moment, reads each entry as the time it happened.

Over times of day, the reduces that keep a time a time are offered: Mean, Median, Min (the earliest), Max (the latest), First and Last. A Sum of times is never offered, since two 06:30 wakes are not 13:00 of anything. A trackable of the time kind defaults to its Mean, and a moment to its Last.

The time kind

What a clock reading produces is the time kind (Value Types): numeric underneath, the way a yes/no is. Every clock time on screen follows the device’s own clock, 12-hour (“11:32 PM”) or 24-hour (“23:32”), as its time fields show it, through one formatter (clockText in apps/renderer/src/lib/clock-text.ts); a stored time and a time field’s value stay HH:mm. It is a kind rather than a unit dimension because it has no unit to prefer or convert. It is on an interval scale, with a zero that is a convention, so a zone over it reads a bound and a distance but never a percentage (scaleOf; Celsius is on the same scale). A distance from a clock bound is a length, and is shown as a length rather than as a clock time.

Comparing against one

A zone on a clock reading is how a time is compared: Snoozed is a zone on Waketime from 06:30, and a derived yes/no can read whether the day sat inside it (Derived Trackables). A clock time typed for a zone bound is placed into the reading’s frame (placeClock), so a 23:00 bound on a bedtime becomes −3600 and matches the nights it should.

On a chart

A start reading is charted noon to noon, so a bedtime either side of midnight sorts in order; every other reading is charted midnight to midnight (clockFrameStart). Axis ticks fall on whole steps of time, 15 or 30 minutes, or 1, 2, 3, 6 or 12 hours (timeTicks).

A Timeline lays out each day’s 24 hours, and has to cut the day somewhere. Where it cuts is its Day Boundary. Left on Auto, it is midnight unless the entries cross midnight, and then the middle of the longest stretch of hours they cover least, mid-afternoon for most people’s sleep (autoStart in apps/renderer/src/lib/timeline.ts); it can also be pinned to an hour. The Day Boundary belongs to the drawing alone. Which day an entry counts for comes from its trackable (a sleep by its waketime, through Entry date on its interval field, Intervals), and the app’s Today turns over at midnight.

Suggesting a time

usualTimeOfDay gives the median time of a trackable’s last 30 entries, to the five minutes, or nothing with fewer than three. It is offered as a suggestion when placing a trackable at a time in the day and never orders anything by itself, because a time that moves as you log would reorder the day’s list under your thumb.

Readings · Value Types · Intervals · Sleep · Derived Trackables · Derived Authoring