DevToolsHub
Cheat Sheet

Unix Timestamp Cheat Sheet for Developers

June 24, 20266 min read

Every developer hits timestamps at some point. JWT expiration (exp), API pagination cursors, database audit fields — Unix timestamps are everywhere. Yet they're one of the most common sources of confusion (and bugs).

This cheat sheet covers everything: conversion tricks, the seconds vs millisecondstrap, timezone gotchas, and one-liners for every major language.

⏱ Quick Try

Convert timestamps instantly with our free Timestamp Converter — supports seconds, milliseconds, and multiple timezone formats.

Quick Reference: Common Timestamps

Date/Time (UTC)Unix (seconds)Unix (ms)
Jan 1, 1970 00:00:0000
Jan 1, 2000 00:00:00946684800946684800000
Jan 1, 2020 00:00:0015778368001577836800000
Now (Jun 2026)~1782000000~1782000000000
Jan 19, 2038 03:14:0721474836472147483647000

⚠️ Year 2038 Problem

The last row shows 2,147,483,647 — the maximum value for a signed 32-bit integer. After this point, 32-bit systems will overflow. Most modern systems use 64-bit timestamps (safe for 292 billion years), but embedded systems and legacy APIs may still be vulnerable.

The #1 Bug: Seconds vs Milliseconds

This is the most common timestamp bug in existence:

  • JavaScript Date.now()milliseconds
  • Python time.time()seconds (as float)
  • JWT exp claim → seconds
  • PostgreSQL EXTRACT(EPOCH FROM NOW())seconds
  • MySQL UNIX_TIMESTAMP()seconds

Rule of thumb:If the value is around 1.7 billion → it's seconds. If it's around 1.7 trillion → it's milliseconds. The current epoch (June 2026) is about 1,782,000,000 in seconds.

Our Timestamp Converter automatically detects whether your input is seconds or milliseconds — just paste and it works.

One-Liners for Every Language

JavaScript / TypeScript

// Current time
Date.now()                         // -> 1782000000000 (ms)
Math.floor(Date.now() / 1000)      // -> 1782000000 (s)

// Timestamp to Date
new Date(1782000000000)            // -> 2026-06-24T... (ms)
new Date(1782000000 * 1000)        // -> same, but for seconds input

// Date to timestamp
new Date('2026-06-24').getTime()   // -> 1758585600000 (ms)
+new Date()                        // -> shorthand for Date.now()

// Format timestamp
new Date(1782000000000).toISOString()  // -> "2026-06-24T12:00:00.000Z"

Python

import time, datetime

# Current time
time.time()                        # -> 1782000000.123 (seconds, float)

# Timestamp to datetime
dt = datetime.datetime.fromtimestamp(1782000000)
print(dt.strftime('%Y-%m-%d %H:%M:%S'))

# Datetime to timestamp
dt = datetime.datetime(2026, 6, 24)
dt.timestamp()                     # -> 1758585600.0

# Timezone-aware (recommended)
from datetime import timezone
dt_utc = datetime.datetime.fromtimestamp(1782000000, tz=timezone.utc)

SQL (PostgreSQL)

-- Current Unix timestamp (seconds)
SELECT EXTRACT(EPOCH FROM NOW())::bigint;

-- Timestamp to date
SELECT to_timestamp(1782000000);

-- Date to timestamp
SELECT EXTRACT(EPOCH FROM TIMESTAMP '2026-06-24 12:00:00')::bigint;

-- Check if JWT is expired
SELECT 1782000000 > EXTRACT(EPOCH FROM NOW())::bigint; -- false = expired

Bash / Shell

# Current timestamp
date +%s                    # -> 1782000000 (seconds)

# Timestamp to date
date -d @1782000000         # macOS: date -r 1782000000

# Date to timestamp
date -d "2026-06-24" +%s   # -> 1758585600

# ISO format
date -u -d @1782000000 +"%Y-%m-%dT%H:%M:%SZ"

Java

// Current time (milliseconds)
System.currentTimeMillis();        // -> 1782000000000L

// Convert to seconds
System.currentTimeMillis() / 1000;

// Timestamp to Instant
Instant.ofEpochSecond(1782000000);
Instant.ofEpochMilli(1782000000000L);

// Format
Instant.now().toString();          // -> "2026-06-24T12:00:00Z"

// JWT exp check
long exp = 1782000000L;
boolean expired = Instant.now().getEpochSecond() > exp;

Go

// Current time
time.Now().Unix()              // -> 1782000000 (seconds)
time.Now().UnixMilli()         // -> 1782000000000 (ms)

// Timestamp to readable
t := time.Unix(1782000000, 0)
fmt.Println(t.Format(time.RFC3339))

// Parse to timestamp
t, _ := time.Parse(time.RFC3339, "2026-06-24T12:00:00Z")
t.Unix()                       // -> 1782000000

Rust

use std::time::{SystemTime, UNIX_EPOCH};

// Current timestamp
let now = SystemTime::now()
    .duration_since(UNIX_EPOCH)
    .unwrap();
println!("{}", now.as_secs());       // seconds
println!("{}", now.as_millis());      // ms

Common JWT Timestamp Patterns

If you're decoding JWTs (use our JWT Decoder), you'll frequently need to check these timestamp claims:

  • exp — Token expiration (always in seconds)
  • iat — Token issued at (seconds)
  • nbf — Not valid before (seconds)

Copy the exp value into the Timestamp Converter to instantly see if a token is expired — it color-codes expired vs valid.

Time Zones: The Hidden Trap

Unix timestamps are always UTC.They don't have a timezone. A timestamp of 1782000000means the same moment everywhere on Earth — it's the display that varies by timezone.

When converting timestamps to readable dates:

  • Use ISO 8601 format (e.g., 2026-06-24T12:00:00Z) for communication between systems — the trailing Z means UTC
  • Only convert to local time when presenting to users
  • Never store timestamps in local time — always use Unix timestamps or UTC ISO strings

🎯 Summary

  • Unix timestamps = seconds since Jan 1, 1970 UTC
  • JS uses milliseconds, most backends use seconds
  • Timestamps are always UTC — timezone is a display concern
  • Use our Timestamp Converter for quick conversions
  • Check JWT expiration with our JWT Decoder

Common Mistakes & How to Avoid Them

Even experienced developers hit these timestamp traps. Here are the four most common bugs and how to fix them.

1. Comparing seconds with milliseconds

The classic JWT bug: exp is in seconds but Date.now() returns milliseconds. The comparison always evaluates the wrong way — silently.

// BUG: exp (seconds) vs Date.now() (ms) — token always looks expired
if (Date.now() > jwt.exp) { /* reject */ }

// FIX: convert exp to milliseconds first
if (Date.now() > jwt.exp * 1000) { /* correct */ }

2. Passing timestamps to Date() as strings

new Date("1782000000") does not parse a numeric timestamp — it tries to parse a date string and returns Invalid Date in most engines. Pass a number, and remember that JS Date works in milliseconds.

new Date("1782000000")      // Invalid Date — string, not number
new Date(1782000000)        // 1970-01-21 — seconds treated as ms!
new Date(1782000000 * 1000) // correct for seconds input

3. Rounding negative timestamps

Pre-1970 timestamps are negative. Math.round(-0.6) gives -1 and Math.floor(-0.6) also gives -1 — both shift the second. Use Math.trunc (or integer division) when converting float seconds to integers so the value stays stable.

4. Storing timestamps in 32-bit columns

MySQL INT and PostgreSQL integer max out at 2,147,483,647 — that is January 19, 2038. Use BIGINT for Unix seconds (or the database native timestamp type) so your schema survives the 2038 rollover.

Frequently Asked Questions

How do I tell if a timestamp is in seconds or milliseconds?
Count the digits. Seconds timestamps for the current era have 10 digits (about 1.78 billion), while milliseconds timestamps have 13 digits (about 1.78 trillion). If the value is near 1,700,000,000 it is seconds; if it is near 1,700,000,000,000 it is milliseconds. JWT claims (exp, iat,nbf) always use seconds.
What is the Year 2038 problem and should I worry about it?
On January 19, 2038 at 03:14:07 UTC, a signed 32-bit integer reaches its maximum value (2,147,483,647) and overflows, breaking systems that store timestamps in 32-bit integers. Modern 64-bit systems are safe for about 292 billion years. Check embedded devices, old embedded databases, and legacy APIs — and always use 64-bit types or BIGINT columns in new code.
How do I convert a Unix timestamp to a specific time zone?
A Unix timestamp is a single instant in UTC — it has no time zone of its own. The time zone only matters when formatting for display. In JavaScript use toLocaleString() or Intl.DateTimeFormat; in Python pass tz to datetime.fromtimestamp(). Keep timestamps and ISO strings in UTC for storage and only convert at the presentation layer.
Why does new Date(1782000000) return a date in 1970?
JavaScript Date counts milliseconds since the epoch, so 1782000000 is only about 20.6 days after January 1, 1970. Multiply seconds by 1000 first: new Date(1782000000 * 1000). This is the single most common timestamp bug in JavaScript.
Can a Unix timestamp be negative?
Yes. Any instant before January 1, 1970 UTC is a negative number — for example, December 31, 1969 23:59:00 UTC is -60. Some older systems and naive parsers reject negative values, and rounding functions behave differently on negatives, so handle them explicitly if your data can predate 1970 (birth dates, historical records, and so on).