Time Marker (ISO 8601) Validator
Validate ISO 8601 full timestamp format with UTC, offsets and millis.
Timestamp: anchoring an instant in a single integer
A timestamp (or Unix timestamp / epoch time) is the number of units (typically seconds, milliseconds, microseconds or nanoseconds) elapsed since the Unix epoch: midnight UTC on 1970-01-01. It is the most compact, language-agnostic way to represent an instant in time, which is why it dominates databases, log files, distributed systems and protocol headers. This validator checks well-formed timestamps and helps you spot the unit (s/ms/us/ns) automatically.
Unlike ISO 8601 strings, a timestamp is unambiguous: it is always UTC, with no timezone or DST to interpret. Display is the consumer's responsibility — store the integer, render the local time at the edge. The drawback: a timestamp is opaque to humans, and the wrong unit silently shifts the value by 3, 6 or 9 orders of magnitude.
Variants: seconds, milliseconds, microseconds, nanoseconds
In 2024 the digit count is the easiest way to detect the unit (the magnitude rule). Around the year 2024 the boundaries are:
- Seconds (10 digits) —
1700000000= 2023-11-14T22:13:20Z. Used by Unixtime(2), PostgresEXTRACT(EPOCH FROM ts), Linux, MySQLUNIX_TIMESTAMP(). - Milliseconds (13 digits) —
1700000000000. JavaScriptDate.now(), JavaSystem.currentTimeMillis(), Kafka. - Microseconds (16 digits) —
1700000000000000. Postgres internaltimestamp, Pythondatetime.timestamp() * 1e6. - Nanoseconds (19 digits) —
1700000000000000000. Gotime.UnixNano(), Prometheus internal, OpenTelemetry traces.
Magnitude detection in pseudo-code: if (ts < 1e10) seconds; else if (ts < 1e13) ms; else if (ts < 1e16) us; else ns; — works for every realistic value between ~2001 and ~2286.
Validation rules
A robust timestamp validator combines two checks:
- Syntactic — integer (or string of digits), optionally negative. Regex:
/^-?\d+$/. - Semantic / sanity — the resulting date should land in a plausible window (e.g. 1970-2100). Reject 12-digit values like
123456789012that are neither valid seconds nor valid ms.
function detectUnit(n) {
if (n < 1e10) return 's';
if (n < 1e13) return 'ms';
if (n < 1e16) return 'us';
return 'ns';
}
The Y2038 problem
A signed 32-bit integer can only count up to 2^31 - 1 = 2147483647. That value as a Unix second is 2038-01-19T03:14:07Z — the moment 32-bit Unix systems wrap around to 1901. This is the modern Y2K, and it affects embedded devices, IoT firmware, old MySQL TIMESTAMP columns, ext3 inodes, NTP packets and many file formats.
Mitigations in production today:
- 64-bit
time_t— default in glibc since 2.34 on 32-bit ARM, in the Linux kernel viaCONFIG_64BIT_TIMEfrom 5.6, and standard on all 64-bit systems. - MySQL — switch
TIMESTAMPtoDATETIME, which uses literal year storage. - Postgres — uses 64-bit microseconds internally and is safe past the year 294276.
- JavaScript / Java / Python — already 64-bit, no fix needed.
Timestamps vs ISO 8601 vs RFC 3339
- Timestamp (integer) — compact, unambiguous, hard to read. Best for storage and protocols.
- ISO 8601 — long human-readable string, supports timezones, durations and intervals.
- RFC 3339 — strict subset of ISO 8601 used by Internet protocols.
2024-03-15T10:30:00Zis RFC 3339;2024-W11-5is ISO 8601 but not RFC 3339.
Negative timestamps work too: -867844800 represents Apollo 11 launch (1969-07-16T13:32:00Z), about 6 months before the epoch. Some legacy systems do not accept negative values — beware.
DST, timezones and Brazil's special case
A timestamp is always UTC. Displaying it requires a timezone, and DST transitions cause the famous "1:30 AM happens twice" bug. Brazil abolished daylight saving in 2019, so BRT is now a fixed UTC-3 year-round (Acre stays at UTC-5). This makes America/Sao_Paulo a particularly stable timezone for new applications — but legacy data from 1985-2019 still carries the old DST rules in IANA's tzdata.
Converting in different languages
// JavaScript (ms)
new Date(1700000000000).toISOString();
// Python (s)
from datetime import datetime, timezone
datetime.fromtimestamp(1700000000, tz=timezone.utc)
// Go (ns)
time.Unix(0, 1700000000000000000).UTC()
// SQL (Postgres)
SELECT to_timestamp(1700000000);
// shell
date -u -d @1700000000
NTP and clock accuracy
A timestamp is only as good as the clock that produced it. NTP (Network Time Protocol) keeps servers within a few milliseconds of UTC; chrony is the modern Linux replacement for the legacy ntpd daemon, with better recovery after suspend/resume. Cloud providers offer hosted NTP (AWS Time Sync, Google Public NTP) and high-frequency trading uses PTP (Precision Time Protocol, RFC 5905-class) for sub-microsecond accuracy.
FAQ
Should I store seconds or milliseconds?
Depends on the platform. JavaScript ecosystems gravitate to ms because Date.now() returns ms. Backend Unix/Postgres ecosystems prefer seconds. Be consistent within one system — silent unit conversion is the most common timestamp bug.
Is Y2038 still a real risk?
Yes, especially in embedded firmware, industrial controllers, smart meters and old MySQL TIMESTAMP columns that were never migrated. Modern 64-bit OSes are fine, but the legacy long tail is large.
How do I convert a ms timestamp in JavaScript?
new Date(ms). For seconds, multiply by 1000 first: new Date(s * 1000). For ns, divide by 1e6 — but JavaScript Numbers lose precision above 2^53, so use BigInt for nanoseconds.
Are leap seconds counted?
The classic Unix epoch ignores leap seconds — it treats every day as 86400 seconds. This is a deliberate simplification; the actual leap second is "smeared" by Google Public NTP and AWS Time Sync to avoid the 23:59:60 anomaly. POSIX time is therefore an approximation of UTC, not a strict UTC count.
Can a timestamp be negative?
Yes — values before 1970-01-01 are negative. Most modern libraries accept them, but legacy C code, MySQL TIMESTAMP and many spreadsheet formats do not. If you store historical dates (births before 1970, geology, history), prefer ISO 8601 strings.
Related Tools
CPF Validator
Validate Brazilian CPF numbers instantly using the official algorithm. Useful for testing document validation in applications. No data sent to servers.
Batch CPF Validator
Validate a list of CPFs (one per line) and see which are valid and which are not. No data sent to servers.
Batch CNPJ Validator
Validate a list of CNPJs (one per line) with a summary of valid, invalid and total. No data sent to servers.