Online Tools Toolshu.com Log In Sign Up

Unix Timestamp Complete Guide: How It Works, Timezone Pitfalls, and Code for Every Language

Original Author:bhnw Released on 2026-04-06 22:49 1 views Star (0)

What Is a Timestamp

Open any database and you might see a field like created_at storing a value like 1712345678 — a seemingly meaningless integer. That is a Unix timestamp: the most universal way computers represent time.

A Unix timestamp is the number of seconds that have elapsed since January 1, 1970, at 00:00:00 UTC (Coordinated Universal Time).

This starting point is called the Unix Epoch, or simply "epoch time." The year 1970 was chosen because Unix was born around 1969-1970, making it a convenient and sufficiently modern reference point for early developers.


Why Use Timestamps Instead of Date Strings

Why not just store "2024-04-06 10:30:00"? In practice, timestamps have several critical advantages over date strings in system development:

1. No timezone ambiguity

Is "2024-04-06 10:30:00" Beijing time or New York time? Impossible to tell. The timestamp 1712374200, on the other hand, always refers to exactly one moment in time, independent of any timezone.

2. Easy arithmetic

Subtract two timestamps to get the exact difference in seconds. Checking whether an event occurred within the last hour: now - event_time < 3600. Simple and unambiguous.

3. Storage efficiency

A 32-bit integer uses just 4 bytes, while a date string requires at least 19 bytes.

4. Universal across languages and platforms

Every programming language and operating system supports Unix timestamps with no format compatibility issues.


Seconds vs. Milliseconds: The Most Common Trap

Timestamps come in two precisions, and this is where beginners most often go wrong:

Precision Example Digits Common usage
Seconds (s) 1712374200 10 digits Unix standard, databases, server logs
Milliseconds (ms) 1712374200000 13 digits JavaScript, frontend, high-precision logging

JavaScript's Date.now() returns milliseconds, which is the source of many bugs. Passing a millisecond timestamp to a backend that expects seconds will produce a date tens of thousands of years in the future.

Quick identification rule: 10 digits = seconds, 13 digits = milliseconds.

// JavaScript: get seconds-precision timestamp
Math.floor(Date.now() / 1000)  // correct
Date.now()                      // milliseconds — be careful
# Python: get timestamp
import time
time.time()        # float, seconds (with decimals)
int(time.time())   # integer seconds

Timestamp Code for Every Language

JavaScript / Node.js

// Get current timestamp (seconds)
const ts = Math.floor(Date.now() / 1000);

// Timestamp to date
const date = new Date(ts * 1000);
console.log(date.toISOString()); // "2024-04-06T02:30:00.000Z"

// Date string to timestamp
const ts2 = Math.floor(new Date("2024-04-06T10:30:00+08:00").getTime() / 1000);

Python

import time
from datetime import datetime, timezone

# Get current timestamp (seconds)
ts = int(time.time())

# Timestamp to date (UTC)
dt_utc = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt_utc.isoformat())  # "2024-04-06T02:30:00+00:00"

# Timestamp to local time
dt_local = datetime.fromtimestamp(ts)
print(dt_local)  # displayed in system timezone

# Date string to timestamp
dt = datetime.fromisoformat("2024-04-06T10:30:00+08:00")
ts2 = int(dt.timestamp())

Java

import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.ZoneId;

// Get current timestamp (seconds)
long ts = Instant.now().getEpochSecond();

// Timestamp to date
Instant instant = Instant.ofEpochSecond(ts);
ZonedDateTime zdt = instant.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zdt); // 2024-04-06T10:30:00+08:00[Asia/Shanghai]

// Date to timestamp
ZonedDateTime zdt2 = ZonedDateTime.parse("2024-04-06T10:30:00+08:00");
long ts2 = zdt2.toEpochSecond();

Go

import (
    "fmt"
    "time"
)

// Get current timestamp (seconds)
ts := time.Now().Unix()

// Timestamp to date
t := time.Unix(ts, 0).UTC()
fmt.Println(t.Format(time.RFC3339)) // "2024-04-06T02:30:00Z"

// Date to timestamp
layout := "2006-01-02T15:04:05Z07:00"
t2, _ := time.Parse(layout, "2024-04-06T10:30:00+08:00")
ts2 := t2.Unix()

PHP

// Get current timestamp (seconds)
$ts = time();

// Timestamp to date
echo date('Y-m-d H:i:s', $ts);    // server timezone
echo gmdate('Y-m-d H:i:s', $ts);  // UTC

// Date to timestamp
$ts2 = strtotime('2024-04-06 10:30:00'); // server timezone

MySQL

-- Get current timestamp
SELECT UNIX_TIMESTAMP();

-- Timestamp to date
SELECT FROM_UNIXTIME(1712374200);
SELECT FROM_UNIXTIME(1712374200, '%Y-%m-%d %H:%i:%s');

-- Date to timestamp
SELECT UNIX_TIMESTAMP('2024-04-06 10:30:00');

Timezones: Where Things Go Wrong

A timestamp itself is timezone-agnostic, but converting a timestamp to a human-readable date always requires a timezone. Without one, the system default timezone is used — a silent hazard in server deployments: your local machine might be CST (+8) while the production server runs UTC (+0), making the same timestamp display 8 hours differently.

Best practices:

  1. Store and transmit timestamps in UTC — never store timezone-embedded strings
  2. Convert to the user's local timezone only at display time, with conversion logic in the frontend or explicitly specified
  3. Never rely on the system's default timezone in code — always pass the timezone explicitly
# Wrong: relies on system timezone
datetime.fromtimestamp(ts)  # behavior depends on deployment environment

# Correct: explicit timezone
datetime.fromtimestamp(ts, tz=timezone.utc)

The Year 2038 Problem

Unix timestamps were originally stored as 32-bit signed integers, with a maximum value of 2147483647 — corresponding to January 19, 2038, at 03:14:07 UTC. After that moment, a 32-bit integer overflows to a negative number, and the represented time wraps back to 1901.

This is the Y2K38 problem, analogous to the original Y2K millennium bug.

The good news: most modern systems have migrated to 64-bit integer timestamps, which can represent dates roughly 292 billion years into the future. The concern applies to legacy systems, embedded devices, and specific database column types — MySQL's TIMESTAMP type has a 2038 ceiling, while DATETIME does not.


Online Tool

To quickly convert a timestamp to a readable date, or turn a specific date into a timestamp, the Timestamp Online Converter on toolshu.com supports both seconds and milliseconds precision, with full global timezone switching — no installation required.

发现周边 发现周边
Comment area

Loading...