time Element and Datetime
Mark up dates and times with time and datetime — machine-readable values, accessible display text, and formatting with Intl.
- html
- time
- datetime
The <time> element represents a date, time, or duration. The optional datetime attribute holds a machine-readable value while the element’s children hold what humans see. That split is the whole point.
Docs: MDN <time>, HTML date strings, Intl.DateTimeFormat.
Basic patterns
<p>
Published
<time datetime="2026-08-04">August 4, 2026</time>
</p>
<p>
Launch at
<time datetime="2026-08-04T15:30:00-07:00">3:30 p.m. PDT</time>
</p>
<p>
Duration
<time datetime="PT2H30M">2 hours 30 minutes</time>
</p>
Valid datetime forms include:
- Date:
2026-08-04 - Time:
15:30/ with seconds - Local date-time with offset or
Z - Year-month, week, durations (
P…/PT…) per HTML rules
If you omit datetime, the text content must itself be a valid machine-readable value — usually harder for localized display. Prefer explicit datetime.
Why bother?
- Consistent parsing for scripts and potential rich results
- Clear semantics vs a random
<span> - Pairs with styling (
time { font-variant-numeric: tabular-nums; }) - Microdata/open-graph ecosystems sometimes consume dates nearby
It is not a full replacement for calendar widgets or input type="date".
Display with Intl
const el = document.querySelector("time");
const instant = new Date(el.dateTime);
el.textContent = new Intl.DateTimeFormat(undefined, {
dateStyle: "medium",
timeStyle: "short",
}).format(instant);
<time datetime="2026-08-04T22:30:00Z" data-relative>…</time>
Generate localized visible text in the user’s locale; keep datetime in an unambiguous absolute form (UTC or offset).
Relative times
function formatRelative(iso) {
const rtf = new Intl.RelativeTimeFormat(undefined, { numeric: "auto" });
const deltaSec = Math.round((new Date(iso) - Date.now()) / 1000);
const abs = Math.abs(deltaSec);
if (abs < 60) return rtf.format(Math.round(deltaSec), "second");
if (abs < 3600) return rtf.format(Math.round(deltaSec / 60), "minute");
if (abs < 86400) return rtf.format(Math.round(deltaSec / 3600), "hour");
return rtf.format(Math.round(deltaSec / 86400), "day");
}
Show relative text visually but leave absolute datetime for precision (tooltips title attribute can show absolute).
<time datetime="2026-08-04T12:00:00Z" title="August 4, 2026, 12:00 UTC">
2 hours ago
</time>
Accessibility
- Visible text should be understandable without hovering.
- Don’t rely only on relative “2h” without context in critical flows (legal deadlines).
- Ensure color contrast if timestamps are muted gray.
Interview out-loud
“<time datetime> separates machine-readable instants from human-readable display. I put ISO-like values in datetime and localize the text with Intl. Relative times keep an absolute datetime for precision. It’s semantic markup for dates—not an input control.”
Footguns
- Local strings only in text with no
datetime. - Ambiguous
08/04/2026as the only value (locale order). - Updating relative labels without refreshing (stale “2 hours ago”).
- Using time for non-temporal text.
- Off-by-timezone bugs when parsing date-only as UTC midnight.
Server render + hydrate
Render absolute datetime and a reasonable default absolute display from the server (UTC or author locale). On the client, optionally replace the visible text with localized or relative formatting. Avoid empty time nodes waiting for JS — crawlers and no-JS users should still see a date.
<time datetime="2026-08-04T12:00:00Z">4 Aug 2026, 12:00 UTC</time>
That string is truthful without JS; client enhancement can improve locale fit later.
Scheduling UIs
Show both absolute and relative forms for meetings:
<p>
Starts
<time datetime="2026-08-04T17:00:00-07:00">Aug 4, 2026, 5:00 p.m. PDT</time>
(<span data-relative-for="2026-08-04T17:00:00-07:00">in 3 days</span>)
</p>
Store instants in UTC on the server; convert for display. Be explicit about time zones in UI copy when attendees span regions — ISO offsets in datetime help machines, humans need zone abbreviations or city names.
Related
Further reading
Related guides
- Accessibility Tree OverviewHow browsers build the accessibility tree from DOM and CSS — roles, names, states, what’s pruned, and how to inspect it in DevTools.
- Audio and Video ElementsNative audio/video — controls, sources, captions, autoplay policies, and accessibility requirements for media on the web.
- Autocomplete and Name Attributesname and autocomplete on form fields — password managers, autofill tokens, and why missing names break real users more than demos.
- Base Element and Relative URLsHow <base href> rewrites relative URLs for links, scripts, and forms — powerful for static hosts, dangerous when set accidentally.
- contenteditable Basicscontenteditable surfaces — what the browser gives you, sanitization, keyboard and a11y gaps, and when to pick a real editor library.