What epoch time is, and why everything uses it
Unix time counts the seconds elapsed since midnight UTC on 1 January 1970. It is a single integer with no timezone, no calendar, no daylight saving and no locale — which is precisely why it has become the way computers agree about when something happened.
Every complication of human timekeeping sits above it. Timezones, leap years, calendars, formatting conventions and daylight saving are all presentation concerns applied at the edge, and none of them affect the stored value. Two systems on opposite sides of the world holding the same epoch value agree exactly.
The practical rule that follows: store UTC, convert for display. Storing local times means storing an ambiguity, and the hour that repeats every autumn when the clocks go back is where that ambiguity turns into a real bug.
Seconds versus milliseconds — the mistake everyone makes
Unix time is defined in seconds, and most backends, databases and APIs use seconds. JavaScript is the notable exception: Date.now() and the Date constructor work in milliseconds, which is why the confusion is endemic in web codebases where the two meet.
Getting it wrong puts you out by a factor of a thousand. A millisecond value read as seconds lands tens of thousands of years in the future. A second value read as milliseconds lands a few days after 1 January 1970. Both are obvious the moment you look at the resulting date, and completely invisible if you only look at the number.
The reliable tell is length. A current timestamp in seconds is ten digits; in milliseconds it is thirteen. This page detects it and tells you which it assumed rather than converting silently.
Where epoch time breaks down
The best-known limit is 2038. Systems storing Unix time in a signed 32-bit integer overflow on 19 January that year and wrap around to 1901. Modern platforms use 64-bit values and are fine, but embedded devices, older databases and fixed-width file formats can still be exposed — and unlike the year 2000, the affected systems are often the ones nobody is maintaining.
Leap seconds are the subtler problem. Unix time pretends every day has exactly 86,400 seconds, which is not quite true — occasionally a leap second is inserted to keep clocks aligned with the earth's rotation. Systems handle this by repeating or smearing a second, which means epoch time is not a perfectly monotonic count of real elapsed seconds.
For almost all applications neither matters. For anything measuring precise durations across such an event, or storing dates beyond 2038 in a legacy field, both are worth confirming rather than assuming.
Timezones, and why they belong at the edges
A timestamp has no timezone. What has a timezone is the way you display it, and the same epoch value renders as different wall-clock times depending on where the viewer is and whether daylight saving was in effect on that date.
This is why converting for display should happen as late as possible, ideally in the client that knows the user's timezone. Converting early and storing the result throws away the information needed to display it correctly for anybody else.
The exception worth knowing is future events tied to local time. A meeting at nine in the morning next March is nine in the morning regardless of what a government decides about daylight saving between now and then — so those want a local time plus a timezone identifier, not an epoch value.