Overview & Philosophy
ln-time is applied to semantic HTML5 <time data-ln-time="..." datetime="..."> elements, where datetime contains a Unix timestamp in seconds. On boot and whenever attributes change, it formats the timestamp into a localized string using native browser Intl.DateTimeFormat or Intl.RelativeTimeFormat APIs without external date libraries. When configured for relative display (e.g. data-ln-time="relative"), a shared, single-interval timer periodically updates visible text in place without polling the server.
In ln-ashlar, this zero-dependency progressive enhancement layer upgrades native HTML <time> elements into timezone-aware, localized date displays.
The Localized Datetime Doctrine
A time formatter does not parse complex custom string tokens or manage calendars. It acts strictly as an enhancer of standard HTML `
Key Architectural Advantages
-
Standard-Based Concurrency (Zero Bloat): Offloads formatting entirely to native
Intl.DateTimeFormatandIntl.RelativeTimeFormatAPIs. Bypasses heavy parsing packages to maintain a zero-bloat footprint. - Centralized Interval Timer: Relative timestamps are updated dynamically. To maximize performance, the component runs a single global 60-second background ticker to update all elements on the page, automatically sweeping away orphaned nodes.
-
Reactive Property Mutation: Fully integrates with modern reactive workflows. Any dynamic updates to
datetimeordata-ln-timeattributes via JavaScript are observed and rendered instantly.
For the full guide see the ln-time README and the architecture reference.
Attributes
| Attribute | On | Description |
|---|---|---|
data-ln-time="mode" | <time> | Format mode: relative, short, full, date, time |
datetime="1736952600" | <time> | Unix timestamp in seconds |
data-ln-time-locale="mk" | <time> | Override locale (default: <html lang> or browser) |
Format Modes
| Mode | Example Output | Intl Options |
|---|---|---|
relative | 3 hr. ago, just now, in 2 hr. | Intl.RelativeTimeFormat |
short | Jan 15 / Jan 15, 2024 | { month: 'short', day: 'numeric' } + conditional year |
full | January 15, 2025 at 2:30 PM | { dateStyle: 'long', timeStyle: 'short' } |
date | Jan 15, 2025 | { dateStyle: 'medium' } |
time | 2:30 PM | { timeStyle: 'short' } |
All Modes — Same Timestamp
All elements below use the same datetime value. Hover for full date tooltip.
| Mode | Output | HTML |
|---|
Relative Time — Thresholds
Relative mode picks the best unit and uses Intl.RelativeTimeFormat for localized output. Auto-updates every 60 seconds.
| Offset | Output |
|---|
Future Timestamps
Relative mode handles future dates — Intl.RelativeTimeFormat produces "in X" automatically.
| Offset | Output |
|---|
Locale Override
Default locale comes from <html lang="en">. Override per-element with data-ln-time-locale.
| Locale | Full | Relative |
|---|
Dynamic Insertion (MutationObserver)
Inserting <time> elements via JS auto-initializes them. Try it:
Reactive Attribute Changes
Changing datetime or data-ln-time re-renders automatically.
Edge Cases
| Case | Element | Result |
|---|---|---|
| Empty datetime | Skipped — fallback text preserved | |
| Missing datetime | Skipped — text preserved | |
| Non-numeric datetime | Skipped — not a Unix timestamp | |
| Epoch zero | Rendered normally (Jan 1, 1970) |
API
// Manual init (not needed for normal use — MutationObserver handles it)
window.lnTime(document.body);
// Instance API
const el = document.querySelector('time[data-ln-time]');
el.lnTime.render(); // Force re-render
el.lnTime.destroy(); // Cleanup (remove from auto-update pool)
// Reactive update — just change the attribute
el.setAttribute('datetime', '1700000000');
el.setAttribute('data-ln-time', 'date'); // switch mode