1. Insight
Insight
The problem this article addresses and why it matters.
Every system represents time differently
Unix epoch seconds, Unix epoch milliseconds, ISO 8601, RFC 2822, human-readable strings, relative phrases ("3 days ago"). Every API picks one — and pipelines that bridge multiple APIs spend a non-trivial amount of code converting between them. The conversion isn't hard; it's just repetitive enough that every developer has written the same new Date(...).toISOString() call hundreds of times.
The real value of a converter isn't doing one conversion — it's doing all the conversions in one call. Paste any timestamp in any format, get every other format back simultaneously. The detection is what saves time: not "convert this epoch to ISO" but "this is an epoch, here's the ISO, here's the RFC 2822, here's the human-readable, here's the relative."
Why a multi-format roundtrip with auto-detect
The tool in this article auto-detects the input format from the input shape — epoch seconds vs milliseconds, ISO 8601 vs RFC 2822, human-readable vs relative ("3 days ago"). The output contains every format in parallel. Multi-timezone output is one parameter away: pass an array of IANA timezones, get the same instant rendered in each.
Useful for normalising heterogeneous timestamps from different APIs into a single canonical representation, or for human-friendly "this happened X ago" displays in a UI.
What this article delivers
Auto-detection walked across the six supported input formats, the multi-timezone output mode against a worldwide schedule, and the cases where format detection fails (an ambiguous numeric string that could be a year, an epoch, or a phone number).
2. Intent
Intent
What you will be able to do after reading.
By the end of this article you will be able to:
- Convert between epoch seconds, epoch milliseconds, ISO 8601, RFC 2822, human-readable, and relative-time formats
- Use auto-detection mode to handle inputs in any supported format without specifying the source format
- Render the same instant in multiple timezones simultaneously with DST awareness and UTC offsets
- Recognise the format-ambiguity cases where detection falls back to a default and you should pass
fromexplicitly - Parse relative-time phrases ("3 days ago", "in 2 hours", "last Tuesday") into absolute timestamps
The Examples section walks through five input formats and the multi-timezone output.
3. Examples
Examples
Annotated code and worked scenarios.
Before / after: auto-detect from any format
Same instant, five different inputs, one call each:
// Epoch seconds
epochConverter({ value: 1747929892, from: 'auto' });
// Epoch milliseconds
epochConverter({ value: 1747929892141, from: 'auto' });
// ISO 8601
epochConverter({ value: '2026-05-22T15:24:52Z', from: 'auto' });
// Human-readable
epochConverter({ value: 'Friday, May 22 2026 at 3:24 PM UTC', from: 'auto' });
// Relative
epochConverter({ value: '3 days ago', from: 'auto' });Each returns the same output shape:
{
detectedFormat: 'epoch-s' | 'epoch-ms' | 'iso8601' | 'human' | 'relative',
epoch: 1747929892, // Unix timestamp seconds
epochMs: 1747929892141, // Unix timestamp milliseconds
iso8601: '2026-05-22T15:24:52.141Z',
rfc2822: 'Fri, 22 May 2026 15:24:52 +0000',
human: 'Friday, May 22, 2026 at 3:24 PM UTC',
relative: '3 days ago',
}Every format returned for every input. Pick whichever the downstream consumer needs.
Before / after: multi-timezone output
epochConverter({
value: 1747929892,
from: 'auto',
outputTimezones: ['America/New_York', 'Europe/London', 'Asia/Tokyo'],
});
// multiTimezone: [
// { timezone: 'America/New_York', iso8601: '2026-05-22T11:24:52-04:00', human: 'Fri, May 22 2026 at 11:24 AM EDT', offset: '-04:00', isDST: true },
// { timezone: 'Europe/London', iso8601: '2026-05-22T16:24:52+01:00', human: 'Fri, May 22 2026 at 4:24 PM BST', offset: '+01:00', isDST: true },
// { timezone: 'Asia/Tokyo', iso8601: '2026-05-23T00:24:52+09:00', human: 'Sat, May 23 2026 at 12:24 AM JST', offset: '+09:00', isDST: false },
// ]Notice Tokyo crosses midnight — same instant, different calendar date. Useful for "when does this run worldwide?" displays in a global team's scheduling UI.
Before / after: relative-time parsing
epochConverter({ value: 'in 2 hours', from: 'relative' });
// epoch: <current epoch + 7200>
epochConverter({ value: 'last Tuesday', from: 'relative' });
// epoch: <the most recent past Tuesday's date at midnight>
epochConverter({ value: '5 days from now', from: 'relative' });
// epoch: <current epoch + 5 * 86400>Useful for natural-language inputs in search UIs ("orders from the last week") that need to translate to absolute timestamps for database queries.
When humans use this
A developer normalising timestamps from a third-party API uses auto-detect to handle whatever format the API ships, then picks the canonical representation for their database. A team building a "what time is this meeting in my timezone?" feature uses the multi-timezone output to render the same calendar event in every team member's local time.
When agents use this
Two patterns:
- Timestamp normalisation. An agent ingesting timestamps from heterogeneous sources runs each through auto-detect and stores the ISO 8601 form as canonical. Pipeline-wide consistency without per-source format handling.
- Relative-time UI. An agent generating UI copy ("posted 3 hours ago") gets the relative form for free. The relative output is locale-aware in its phrasing.
Edge cases
Ambiguous numeric input
2024 could be a year, an epoch (in 1970, 33 minutes past midnight), or a string. Auto-detect picks based on magnitude: under 1e10 is epoch seconds, 1e10 to 1e13 is epoch milliseconds, four-digit values get flagged as ambiguous with a warning recommending an explicit from parameter.
Timezone handling on input
If the input is naive (no timezone) and no timezone parameter is set, the tool defaults to UTC. Explicit timezone on the input (2026-05-22T15:24:52-04:00) is respected. The timezone parameter applies only when the input has no zone.
Relative-time precision
"3 days ago" is precise to the day, not the millisecond. The tool emits midnight of the relative date. For sub-day relatives ("3 hours ago"), the output is precise to the hour.
4. Documentation
Documentation
Reference signatures, edge cases, and lookup tables.
Input parameters
Field | Type | Required | Default | Description |
|---|---|---|---|---|
|
| ✓ | — | The timestamp to convert |
|
| ✗ |
| Input format |
|
| ✗ |
| IANA timezone for naive inputs |
|
| ✗ | — | Render the instant in multiple zones simultaneously |
Output shape
{
detectedFormat: string;
epoch: number; // Unix seconds
epochMs: number; // Unix milliseconds
iso8601: string;
rfc2822: string;
human: string;
relative: string;
multiTimezone?: Array<{
timezone: string;
iso8601: string;
human: string;
offset: string; // '+05:30'
isDST: boolean;
}>;
}Format detection heuristics
Input shape | Detected as | ||
|---|---|---|---|
Number, < 1e10 |
| ||
Number, 1e10–1e13 |
| ||
String matching |
| ||
String matching `^(Mon | Tue | ...) \d{1,2} \w{3} \d{4}` |
|
String with words like "ago", "now", "from", weekdays |
| ||
Otherwise |
|
Error codes
Code | When it fires | Recovery |
|---|---|---|
|
| Provide a value |
| All format detectors failed to parse the input | Verify the input is a recognised format; pass |
|
| Use canonical IANA names ( |
When NOT to use this tool
For date arithmetic (add 3 days, find the first Monday of the month, count business days between two dates), use a date library (date-fns, dayjs, luxon). The converter handles parsing and formatting; arithmetic is a different scope.
For ISO 8601 duration parsing (P3DT4H5M for "3 days 4 hours 5 minutes"), use a dedicated duration parser. The converter handles instants, not durations.
Performance notes
Typical execution: under 2ms. Multi-timezone output adds <1ms per zone. Deterministic for absolute inputs (epoch, ISO 8601); relative inputs depend on the current wall clock so REST responses set Cache-Control: no-store when from: 'relative'.