Unix Timestamp Seconds vs Milliseconds: How to Tell
A timestamp such as 1800000000 is probably seconds. A timestamp such as 1800000000000 is probably milliseconds. For dates around the present day, count the digits: 10 usually means seconds and 13 usually means milliseconds.
That three-digit difference causes one of the most common date bugs in APIs. The number looks valid, the date constructor accepts it, and the result quietly lands in 1970 or thousands of years in the future.
What a Unix timestamp measures
Unix time counts elapsed time from the Unix epoch: 1970-01-01T00:00:00Z. The conventional unit is seconds, which is why command-line tools and many backend systems call a 10-digit value a Unix timestamp. Read what a Unix timestamp is for the epoch, negative dates, and leap-second model.
Browser and application APIs often need finer precision. JavaScript's Date, for example, represents elapsed milliseconds from the same epoch. Both values describe the same instant; only the scale differs.
The 10-digit and 13-digit rule
Around 2026, a positive epoch value commonly has this shape:
| Precision | Typical digits | One unit means |
|---|---|---|
| Seconds | 10 | 1 second |
| Milliseconds | 13 | 0.001 second |
| Microseconds | 16 | 0.000001 second |
| Nanoseconds | 19 | 0.000000001 second |
The rule works because milliseconds add three decimal places to seconds. It is a heuristic, not a type system: older dates have fewer digits, negative dates include a sign, and sufficiently distant future dates gain digits. Production code should combine magnitude with a plausible range and an explicit API contract.
Convert seconds and milliseconds
Multiply seconds by 1,000 to get milliseconds. Divide milliseconds by 1,000 to get seconds.
const seconds = 1800000000;
const milliseconds = seconds * 1000;
new Date(milliseconds);
Math.floor(Date.now() / 1000); // current whole seconds
Use Math.floor when an API expects a whole-second timestamp. Leaving the decimal fraction may be valid mathematically but rejected by an integer schema. The timestamp converter lets you paste either unit and verify the resulting UTC and local date before shipping it.
In Python, datetime.fromtimestamp(value, tz=timezone.utc) expects seconds, including a fractional part. Java and JavaScript date constructors often work in milliseconds. SQL databases vary by function and column type. Never infer the unit from the language name; check the specific API.
Why the date becomes 1970
Suppose an API returns 1800000000 seconds and JavaScript executes new Date(1800000000). JavaScript reads the number as milliseconds—only about 20.8 days after the epoch—so the result is in January 1970. The fix is new Date(1800000000 * 1000).
The reverse mistake creates an enormous future value. Sending JavaScript's 13-digit Date.now() to a service that expects seconds tells it to move roughly a thousand times farther from 1970.
Safely detect an unknown unit
When legacy data has no documented unit, normalize by magnitude and reject implausible results rather than silently guessing:
function toDate(epoch) {
if (!Number.isFinite(epoch)) throw new TypeError('Invalid timestamp');
const milliseconds = Math.abs(epoch) < 100_000_000_000
? epoch * 1000
: epoch;
const date = new Date(milliseconds);
if (date < new Date('2000-01-01') || date > new Date('2100-01-01'))
throw new RangeError('Timestamp outside expected range');
return date;
}
The threshold separates contemporary seconds from milliseconds, while the range check reflects the application's domain. A birth-date archive and a scheduled-jobs system need different bounds.
UTC, offsets, and ISO strings
An epoch value does not store a time zone. It identifies an instant; formatting applies a zone afterward. new Date(milliseconds).toISOString() produces a UTC ISO 8601 string ending in Z. A local display can have a different calendar date without changing the underlying instant.
If a value shifts by hours rather than decades, the unit is probably correct and the issue is time-zone interpretation. Review UTC offsets explained and use the ISO date converter to compare representations.
A reliable API contract
Name numeric fields with their unit—createdAtSeconds or expiresAtMs—and document whether fractions are allowed. Better yet, use an ISO 8601 string at human-facing boundaries when readability matters, and reserve epoch numbers for contracts where compact arithmetic is valuable.
The practical rule is simple: 10 digits usually means seconds, 13 usually means milliseconds, and JavaScript expects the latter. Convert deliberately, validate the date range, and never let an unlabeled number define its own unit.
Try the tools
Frequently Asked Questions
Is a Unix timestamp in seconds or milliseconds?
Unix time is conventionally measured in seconds since the Unix epoch, but many APIs and languages use milliseconds. Current values are usually 10 digits in seconds and 13 digits in milliseconds. The data contract—not the field name alone—is authoritative.
How do I convert Unix seconds to milliseconds?
Multiply by 1,000. For example, 1,800,000,000 seconds becomes 1,800,000,000,000 milliseconds. In JavaScript, use new Date(seconds * 1000).
Why does my Unix timestamp show a date in 1970?
The timestamp is probably in seconds but the date API interpreted it as milliseconds. A value around 1.8 billion milliseconds is only about 21 days after January 1, 1970. Multiply the input by 1,000 before passing it to a millisecond-based API.
How many digits does a Unix timestamp have?
For present-day positive dates, seconds use 10 digits and milliseconds use 13. Microseconds use about 16 and nanoseconds about 19. Digit count changes across history and the future, so also validate against an expected date range.
Does a Unix timestamp include a time zone?
No. It represents one instant relative to the UTC epoch. A time zone is only applied when formatting that instant for display. The same timestamp can therefore appear as different clock times in Karachi, London, and New York without representing different moments.
Lauren Prescott writes for CodeUtilityKit, where the team builds free, privacy-first developer tools that run entirely in your browser. Every guide is written and reviewed by developers who use these tools daily.