Time, dates, and durations
A time-looking value can represent several different things. Choose the representation before choosing its format. The preset and custom-code examples use the formatting plugin from Number setup.
| Use case | Suggested raw representation | Display/editor |
|---|---|---|
| Transaction or event instant | Date or ISO string with offset | datetime preset; datetime editor |
| Opening hour without a date | "09:30" | Time editor |
| API latency | Number of milliseconds | Number with an explicit ms heading |
| Elapsed job runtime | Number of seconds | Custom elapsed renderer |
| Imported spreadsheet time | Fractional Excel day serial | time preset or spreadsheet format code |
| Authored planning duration | { value: 3, unit: 'hour', elapsed: false } | Duration editor |
1. Render an instant in a chosen timezone
Section titled “1. Render an instant in a chosen timezone”grid.columns = [{ prop: 'occurredAt', name: 'Event time (UTC)', dataGridFormat: { value: { kind: 'preset', preset: 'datetime', locale: 'en-GB', dateStyle: 'medium', timeStyle: 'medium', timeZone: 'UTC', } },}];grid.source = [{ occurredAt: '2026-10-26T14:30:15Z' }];Use preset: 'time' to display only the clock part, or preset: 'date' for only the date. Time styles are short, medium, or long; date styles also support full. Locale supplies the conventional 12/24-hour display, while timeZone controls the zone. Omitting the zone uses the runtime’s zone, which may differ across users. These are distinct inputs to Intl.DateTimeFormat.
The preset does not expose hour12 or hourCycle. For a forced 24-hour clock independently of locale, use an Intl.DateTimeFormat custom cellTemplate, as in the custom numeric renderer pattern, with explicit hour, minute, second, hourCycle: 'h23', and timeZone options.
Use an ISO offset or Z for instants; avoid ambiguous input such as 10/11/2026. Date-only strings represent calendar dates, and should not be treated as a transaction instant.
2. Display elapsed seconds without wrapping at midnight
Section titled “2. Display elapsed seconds without wrapping at midnight”For operations dashboards, 90061 elapsed seconds means 25:01:01, not a time on a calendar. This Core-only renderer handles a nonnegative integer-second contract:
const elapsed = (seconds: number | null) => { if (seconds == null) return ''; const hours = Math.floor(seconds / 3600); const minutes = Math.floor(seconds % 3600 / 60); const remainder = seconds % 60; return `${hours}:${String(minutes).padStart(2, '0')}:${String(remainder).padStart(2, '0')}`;};
grid.columns = [{ prop: 'runtimeSeconds', name: 'Runtime (h:mm:ss)', readonly: true, cellTemplate: (_h, { model, prop }) => elapsed(model[prop]),}];grid.source = [{ runtimeSeconds: 90061 }, { runtimeSeconds: null }];Validate this contract at the data boundary. For fractional seconds, negative intervals, or localized unit words, choose an explicit rounding/sign policy and renderer. Do not format elapsed seconds with new Date(seconds * 1000): that creates an instant and a clock display that wraps after 24 hours. For latency values such as 1.25 milliseconds, use a number format and name the column Latency (ms).
3. Format spreadsheet serials deliberately
Section titled “3. Format spreadsheet serials deliberately”Numeric values passed to date/time formatting use Excel’s 1900 date system, measured in days. They are not Unix timestamps, milliseconds, or elapsed seconds. 0.5 is a half day; 2.25 is two days and six hours. Use bracketed elapsed hours to retain complete days:
grid.columns = [{ prop: 'elapsedDays', name: 'Elapsed (h:mm:ss)', dataGridFormat: { value: { kind: 'code', formatCode: '[h]:mm:ss', } },}];grid.source = [{ elapsedDays: 2.25 }]; // 54:00:00An ordinary hh:mm:ss code shows the clock portion and wraps hours; [h]:mm:ss shows elapsed hours. Convert source seconds to days deliberately (seconds / 86400) only if spreadsheet serials are your chosen data contract. Imported workbooks using another date system require normalization before displaying them.
4. Choose the matching editor
Section titled “4. Choose the matching editor”- Time Editor stores date-free strings such as
09:30or09:30:15; it supports locale, 12-hour, and 24-hour presentation. A time-only string is not an instant and is not automatically parseable by the date/time preset. - Datetime Editor handles date-and-time entry. Decide whether your application stores instants or local calendar values and preserve that contract at the boundary.
- Duration Editor stores authored unit and elapsed/working mode. Its object representation is not an Excel day serial. Working days and months need calendar policy; a numeric formatter does not supply it.
For cross-country tables, show the timezone in the heading or nearby context, and test daylight-saving transitions for instant-based displays. For date-free business opening hours, keep the associated business timezone in application data instead of inventing a date just for formatting.