DEV Community

Snappy Tools
Snappy Tools

Posted on

Unix Timestamps Explained: The Developer's Complete Reference

Unix timestamps are one of those concepts that every developer encounters constantly but rarely stops to fully understand. They appear in log files, database columns, API responses, and cookie headers. This guide covers everything you need to know — from what they are to language-specific conversion code for every major language.

What is a Unix Timestamp?

A Unix timestamp is a single integer representing the number of seconds elapsed since January 1, 1970, 00:00:00 UTC — known as the Unix epoch.

1717200000  ← this is a Unix timestamp
Enter fullscreen mode Exit fullscreen mode

The epoch date (January 1, 1970) was chosen by Bell Labs engineers when designing Unix. It was simply a convenient, recent reference point that allowed 32-bit integers to cover a useful date range (1901–2038). Modern systems use 64-bit integers, extending the range to hundreds of billions of years.

Seconds vs Milliseconds: The Gotcha

This is the source of more bugs than almost any other timestamp issue:

System Unit Example
Unix/POSIX Seconds 1717200000 (10 digits)
JavaScript (Date.now()) Milliseconds 1717200000000 (13 digits)
Java (System.currentTimeMillis()) Milliseconds 1717200000000

Rule of thumb: if the number has 13 digits, it's milliseconds. If it has 10 digits, it's seconds. Always check which unit your API or database is using before converting.

Converting a Timestamp to a Date in Every Major Language

JavaScript

// Timestamp → date (JavaScript uses milliseconds)
const date = new Date(1717200000 * 1000);
console.log(date.toISOString()); // "2024-05-31T16:00:00.000Z"
console.log(date.toLocaleString()); // local time

// Current timestamp in seconds
const now = Math.floor(Date.now() / 1000);
Enter fullscreen mode Exit fullscreen mode

Python

import datetime, time

# Timestamp → datetime
dt = datetime.datetime.fromtimestamp(1717200000, tz=datetime.timezone.utc)
print(dt)  # 2024-05-31 16:00:00+00:00

# Current timestamp
print(int(time.time()))
Enter fullscreen mode Exit fullscreen mode

PHP

// Timestamp → formatted date
echo date('Y-m-d H:i:s', 1717200000);  // "2024-05-31 16:00:00" (local)
echo gmdate('Y-m-d H:i:s', 1717200000); // "2024-05-31 16:00:00" (UTC)

// Current timestamp
echo time();
Enter fullscreen mode Exit fullscreen mode

Go

import "time"

t := time.Unix(1717200000, 0).UTC()
fmt.Println(t.Format(time.RFC3339)) // "2024-05-31T16:00:00Z"

// Current timestamp
now := time.Now().Unix()
Enter fullscreen mode Exit fullscreen mode

Ruby

Time.at(1717200000).utc  # => 2024-05-31 16:00:00 UTC
Time.now.to_i             # current timestamp
Enter fullscreen mode Exit fullscreen mode

C# (.NET)

// Timestamp → DateTime
var dt = DateTimeOffset.FromUnixTimeSeconds(1717200000).UtcDateTime;

// Current timestamp
long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
Enter fullscreen mode Exit fullscreen mode

Java

Instant instant = Instant.ofEpochSecond(1717200000L);
LocalDateTime dt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

// Current timestamp
long now = Instant.now().getEpochSecond();
Enter fullscreen mode Exit fullscreen mode

SQL

-- MySQL: timestamp → datetime
SELECT FROM_UNIXTIME(1717200000);  -- '2024-05-31 16:00:00'

-- PostgreSQL: timestamp → timestamptz
SELECT to_timestamp(1717200000);   -- 2024-05-31 16:00:00+00

-- Current timestamp
SELECT UNIX_TIMESTAMP();  -- MySQL
SELECT EXTRACT(EPOCH FROM NOW());  -- PostgreSQL
Enter fullscreen mode Exit fullscreen mode

Timezone Pitfalls

Unix timestamps are always in UTC — they have no timezone. The confusion happens when you convert them to human-readable dates. Different languages apply the local timezone by default:

# Python: fromtimestamp() uses local time!
datetime.datetime.fromtimestamp(0)    # Local time — dangerous
datetime.datetime.utcfromtimestamp(0) # Naive UTC — better
datetime.datetime.fromtimestamp(0, tz=datetime.timezone.utc)  # Timezone-aware UTC — best
Enter fullscreen mode Exit fullscreen mode

Best practice: always work in UTC and only convert to local time at the display layer.

The Year 2038 Problem

Systems that store Unix timestamps in 32-bit signed integers will overflow at:

2,147,483,647 seconds → 19 January 2038, 03:14:07 UTC
Enter fullscreen mode Exit fullscreen mode

After this, the value wraps to a large negative number, jumping back to 1901. This affects:

  • Old databases with INT timestamp columns
  • 32-bit embedded systems
  • Legacy C code using time_t on 32-bit platforms

Modern 64-bit systems are safe until approximately the year 292 billion. If you're writing new code, always store timestamps as BIGINT in databases and 64-bit integer types in code.

What Does Timestamp 0 Mean?

Unix timestamp 0 is the epoch itself: 1970-01-01 00:00:00 UTC.

It's commonly used as a sentinel value meaning "not set" or "no date" in older code. Be careful: some validation code mistakenly treats 0 as invalid when it actually represents a perfectly valid date (January 1, 1970).

Quick Conversion Tool

If you need to convert timestamps without writing code, use the Unix Timestamp Converter — it converts in both directions (timestamp ↔ date), shows the current live timestamp, supports all timezones, and displays relative time. No signup, runs in your browser.

Summary

  • A Unix timestamp is seconds since 1970-01-01 00:00:00 UTC
  • JavaScript and Java use milliseconds — always check which unit you're receiving
  • Convert to local time only at the display layer; store and transmit in UTC
  • Use 64-bit integers to avoid the Year 2038 problem
  • Timestamp 0 = the Unix epoch (January 1, 1970), not "invalid"

Top comments (0)