On this page
- How do you convert a Unix timestamp to a date?
- Convert Unix timestamp to date by hand: the math
- Unix to date code examples in six languages
- How does Unix time zone conversion work?
- Which time format should you output?
- Common datetime conversion mistakes and how to fix them
- How to convert a date back to a Unix timestamp
- Can you convert many timestamps at once?
- Frequently asked questions
How do you convert a Unix timestamp to a date?
A Unix timestamp is the number of seconds since 1 January 1970, 00:00:00 UTC. Converting it means handing that number to a date function and choosing how to print the result.
Take 1700000000 as the running example. It is 14 November 2023, 22:13:20 UTC.
The whole process is three steps:
- Check the unit. A 10 digit value is seconds. A 13 digit value is milliseconds.
- Build a date from the number. Use the function that matches the unit, or scale the value first.
- Format with an explicit time zone. UTC for logs and APIs, a named zone for people.
If you only need one answer right now, paste the number into the Unix timestamp converter. The date, time and timezone fields update as you type, and your timezone is detected from the browser. The Formats list shows the full date and time first, with ISO 8601, relative time, day of year, week of year and milliseconds under Show More Results. Click any value to copy it.
Seconds or milliseconds? The converter reads a 13 digit value as milliseconds and anything else as seconds. If you are unsure which one your system emits, see seconds vs milliseconds vs microseconds.
Convert Unix timestamp to date by hand: the math
You rarely do this manually, but knowing the math makes bugs obvious. In Unix time every day has exactly 86,400 seconds, so division does most of the work.
The leftover 80,000 seconds give the time of day: 22:13:20. The 19,675 whole days give the calendar date. Counting forward from 1 January 1970 through 53 years and 13 leap days lands on 14 November 2023.
That day counting is the part worth leaving to a library. Leap year rules and month lengths are easy to get wrong, and every standard library already has them right.
Unix to date code examples in six languages
Each snippet converts 1700000000 to a date in UTC, then to a named time zone. Pick your language.
JavaScript dates use milliseconds, so multiply seconds by 1000.
const ts = 1700000000;
const date = new Date(ts * 1000);
date.toISOString();
// '2023-11-14T22:13:20.000Z'
date.toLocaleString('en-US', { timeZone: 'America/New_York' });
// '11/14/2023, 5:13:20 PM'Always pass a time zone. Without one, Python returns a naive datetime in the machine's local time.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
ts = 1700000000
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt.isoformat())
# 2023-11-14T22:13:20+00:00
print(dt.astimezone(ZoneInfo('America/New_York')))
# 2023-11-14 17:13:20-05:00date() uses the server's default time zone. Use gmdate() for UTC or a DateTime object for a named zone.
$ts = 1700000000;
echo gmdate('Y-m-d H:i:s', $ts);
// 2023-11-14 22:13:20
$dt = (new DateTime('@' . $ts))
->setTimezone(new DateTimeZone('Europe/Berlin'));
echo $dt->format('Y-m-d H:i:s');
// 2023-11-14 23:13:20Use java.time. For a millisecond value call Instant.ofEpochMilli instead.
import java.time.Instant;
import java.time.ZoneId;
Instant instant = Instant.ofEpochSecond(1700000000L);
System.out.println(instant);
// 2023-11-14T22:13:20Z
System.out.println(instant.atZone(ZoneId.of("Asia/Tokyo")));
// 2023-11-15T07:13:20+09:00[Asia/Tokyo]time.Unix takes seconds and nanoseconds. It returns local time, so call UTC() or In() before formatting.
t := time.Unix(1700000000, 0)
fmt.Println(t.UTC().Format(time.RFC3339))
// 2023-11-14T22:13:20Z
loc, _ := time.LoadLocation("Asia/Kolkata")
fmt.Println(t.In(loc).Format(time.RFC3339))
// 2023-11-15T03:43:20+05:30Both functions print the result in the session time zone, so set it or convert explicitly when the output must be UTC.
-- PostgreSQL
SELECT to_timestamp(1700000000);
SELECT to_timestamp(1700000000) AT TIME ZONE 'UTC';
-- MySQL
SELECT FROM_UNIXTIME(1700000000);The pattern is the same everywhere: one call builds the instant, a second call decides how it is displayed. The reference pages for JavaScript Date on MDN and the Python datetime module list every formatting option.
How does Unix time zone conversion work?
A Unix timestamp has no time zone. It counts seconds from a fixed moment in UTC, so 1700000000 is the same instant in Tokyo and in New York. Only the printed date differs.
Notice that Tokyo is already on the next calendar day. This is why "what date is this timestamp" has no answer until you name a zone.
Should you use a named zone or a fixed offset?
Use a named zone from the IANA time zone database, such as America/New_York or Europe/Berlin. A named zone carries the daylight saving rules, so the library applies the right offset for the date in question.
A fixed offset like -05:00 is only correct for part of the year in places that change their clocks. Adding or subtracting 18,000 seconds by hand has the same flaw, and it also leaves you with a number that no longer represents the real instant.
Where should the time zone be applied?
At the last step, when you format for display. Keep the raw timestamp in storage and in transit, and convert once per reader. The companion post on Unix timestamps and UTC covers offsets in more depth.
In the converter on this site, the Timezone dropdown does exactly this. Change it and every result is recalculated for the new zone while the timestamp stays the same.
Which time format should you output?
Once you have a date object, the time format depends on who reads it. Here is the same instant in the formats developers reach for most.
| Format | Example | Use it for |
|---|---|---|
| ISO 8601 / RFC 3339 | 2023-11-14T22:13:20Z | APIs, logs, JSON, anything a machine parses |
| ISO 8601 with offset | 2023-11-14T17:13:20-05:00 | Keeping the local wall clock time and the instant together |
| Date only | 2023-11-14 | Reports, file names, sortable keys |
| RFC 2822 | Tue, 14 Nov 2023 22:13:20 +0000 | Email and HTTP style headers |
| Long local | Tuesday, November 14, 2023 at 5:13:20 PM EST | User interfaces |
| Relative | 3 hours ago | Feeds and activity lists |
For machine output, default to the profile defined in RFC 3339. It sorts as text, it is unambiguous and it always states the offset.
For a custom pattern such as %Y-%m-%d %H:%M:%S, the strftime builder previews a format string live and switches between Python, PHP, Go and JavaScript syntax.
Common datetime conversion mistakes and how to fix them
When a datetime conversion returns a strange date, the cause is almost always one of these.
| Symptom | Cause | Fix |
|---|---|---|
| Date is in January 1970 | Seconds passed where milliseconds were expected | Multiply by 1000 |
| Year is tens of thousands in the future | Milliseconds passed where seconds were expected | Divide by 1000 and round down |
| Time is off by a whole number of hours | The function formatted in the machine's local zone | Pass the time zone explicitly |
| Off by one hour for part of the year | Fixed offset used in a zone with daylight saving time | Use a named IANA zone |
| Invalid date or NaN | The timestamp arrived as a string with spaces or quotes | Trim it and parse to an integer first |
The unit mistake is easy to check with the example value. Read as milliseconds, 1700000000 is 20 January 1970, 16:13:20 UTC. A date in early 1970 is the classic sign of a missing multiplication.
Code that passes on your laptop and fails on the server usually relies on a local time default. Servers often run in UTC, laptops do not. Name the zone in every formatting call and the two will agree.
datetime.utcfromtimestamp() returns a naive object with no zone attached, and it is deprecated since Python 3.12. Call datetime.fromtimestamp(ts, tz=timezone.utc) instead so the result knows it is UTC.
How to convert a date back to a Unix timestamp
The reverse direction needs one extra piece of information: the time zone the date was written in. "14 November 2023, 22:13:20" is a different instant in every zone.
// JavaScript: the Z marks the input as UTC
Math.floor(new Date('2023-11-14T22:13:20Z').getTime() / 1000);
// 1700000000# Python
from datetime import datetime, timezone
int(datetime(2023, 11, 14, 22, 13, 20, tzinfo=timezone.utc).timestamp())
# 1700000000Leave the zone out and the language assumes local time, which gives a different number on each machine. The converter on the homepage works in both directions: set the Date, Time and Timezone fields and the Unix timestamp field updates to match.
Can you convert many timestamps at once?
Yes. For a column from a log file or a database export, a loop in your language of choice works, and so does a tool built for lists.
The batch converter on this site takes one value per line, in seconds or milliseconds. Each row of the result shows your local date and time followed by the UTC value in ISO 8601. A line that cannot be parsed is marked Invalid, so bad input stands out. You can copy all results or download them as a CSV file with the input and the result side by side.
Batch timestamp converterPaste a list, get a table, download CSV
Got a timestamp and need the date now?
Paste the number and read the date in your own time zone or any other. Seconds and milliseconds both work, and every format is one click to copy.
Frequently asked questions
Your function expects milliseconds and received seconds. A value like 1700000000 read as milliseconds is only about 19.7 days after the epoch, so it lands on 20 January 1970. Multiply the value by 1000 before building the date, or use the function in your language that accepts seconds directly.
The timestamp is correct, but it was formatted in a different time zone than you expected. Many functions use the machine's local zone by default, and servers often run in UTC. Pass the zone explicitly when you format, using a named zone such as Europe/Berlin, and the hours will match.
No. Unix time treats every day as exactly 86,400 seconds and does not count leap seconds. That is why plain division gives the right date and time of day. Standard date libraries follow the same rule, so a timestamp converts to the same calendar date in every language.
A JavaScript Date covers 100,000,000 days on either side of the epoch, which is plus or minus 8,640,000,000,000,000 milliseconds. Anything outside that range produces an Invalid Date. In practice the limit only appears when a value is in the wrong unit, for example microseconds passed as milliseconds.
It can. A string without an offset, such as 2023-11-14 22:13:20, no longer says which instant it means, and a date only string drops the time. Keep the original timestamp as the source of truth, and include the offset or the Z suffix in any string that another system will parse.
