Complete Guide to Unix Timestamps
If you've ever wondered why dates in your database look like 1704067200
instead of "January 1, 2024," you're about to learn about one of computing's most elegant solutions to time tracking. Unix timestamps power everything from your favorite social media apps to banking systems, and honestly, once you understand them, you'll appreciate why they've stuck around for over five decades.
What is a Unix Timestamp?
Think of a Unix timestamp (sometimes called POSIX time or epoch time) as the ultimate countdown timer. Instead of juggling years, months, days, hours, and minutes, we just count seconds from a specific starting point. That starting point? January 1, 1970, at 00:00:00 UTC – what we call the Unix epoch.
Here's what that looks like in practice:
0
= January 1, 1970, 00:00:00 UTC (where it all began)1704067200
= January 1, 2024, 00:00:00 UTC1735689600
= January 1, 2025, 00:00:00 UTC
Pretty neat, right? Each number tells you exactly how many seconds have ticked by since that moment in 1970.
Why January 1, 1970?
You might be wondering, "Why 1970? What's so special about that year?" Well, when Dennis Ritchie and Ken Thompson were building Unix back in the early 1970s, they needed to pick a starting point for their time system. They could've chosen any date, really, but the start of 1970 made sense – it was recent, round, and easy to remember. Little did they know this arbitrary decision would become the foundation for how billions of computers track time today.
Seconds vs. Milliseconds
Here's where things get tricky (and where I've seen countless bugs in production code). Unix timestamps actually come in two flavors, and mixing them up is like confusing kilometers with miles – you'll end up way off course.
Unix Seconds (The OG Format)
1704067200
This is your classic Unix timestamp – 10 digits that'll work just fine until the year 2286. You'll see this everywhere in server-side code:
- Your PostgreSQL and MySQL databases love this format
- REST APIs typically use seconds
- Unix/Linux command-line tools expect this
Unix Milliseconds (The JavaScript Way)
1704067200000
Notice those extra three digits? That's the same moment in time, but JavaScript decided to count in milliseconds instead. Why? Because JavaScript's Date.now()
needed more precision for things like animation timing and performance measurements.
You'll run into milliseconds when working with:
- JavaScript and TypeScript (it's the default)
- Some newer APIs that need sub-second precision
- Browser-based timing operations
Here's the deal: Always know which format you're working with! I can't tell you how many times I've debugged code where someone passed a Unix timestamp in seconds to JavaScript's new Date()
, only to see dates from January 1970. Not fun.
Converting Unix Timestamps
To Human-Readable Dates
JavaScript:
const timestamp = 1704067200;
const date = new Date(timestamp * 1000); // Multiply by 1000 for milliseconds
console.log(date.toLocaleString());
// Output: "1/1/2024, 12:00:00 AM"
Python:
from datetime import datetime
timestamp = 1704067200
date = datetime.fromtimestamp(timestamp)
print(date.strftime('%Y-%m-%d %H:%M:%S'))
# Output: "2024-01-01 00:00:00"
PHP:
$timestamp = 1704067200;
$date = date('Y-m-d H:i:s', $timestamp);
echo $date;
// Output: "2024-01-01 00:00:00"
From Human-Readable to Unix
JavaScript:
const date = new Date('2024-01-01T00:00:00Z');
const timestamp = Math.floor(date.getTime() / 1000);
console.log(timestamp);
// Output: 1704067200
Python:
from datetime import datetime
date = datetime(2024, 1, 1, 0, 0, 0)
timestamp = int(date.timestamp())
print(timestamp)
// Output: 1704067200
SQL:
-- Convert to timestamp
SELECT UNIX_TIMESTAMP('2024-01-01 00:00:00');
-- Convert from timestamp
SELECT FROM_UNIXTIME(1704067200);
Why Unix Timestamps Are Actually Brilliant
Let me tell you why developers have been using Unix timestamps for half a century – they solve so many problems elegantly.
1. Simplicity That Just Works
Instead of wrestling with date objects that have a dozen properties, you get one number. Want to know if Event A happened before Event B? Just compare two integers:
// Easy comparison
if (timestamp1 > timestamp2) {
console.log('Event 1 happened after Event 2');
}
// Easy arithmetic
const oneHourLater = timestamp + 3600; // Add 3600 seconds (1 hour)
2. No More Timezone Headaches
Since Unix timestamps are always in UTC, you don't have to worry about "Is this timestamp in Eastern Time or did someone deploy the code to a server in Tokyo?" The timestamp is the same everywhere – you only convert to local time when showing it to users.
3. Lightweight Storage
Why store "2024-01-01 00:00:00 UTC" (28 characters) when you can store 1704067200
(10 digits)? Your database will thank you.
4. Universal Language
Python, JavaScript, Go, Rust, PHP – doesn't matter. Every language speaks Unix timestamp. It's like the Esperanto of time tracking, except people actually use it.
5. Sorting? Done
Want to sort events chronologically? Just sort the numbers. Bigger number = later time. That's it.
Common Pitfalls and Solutions
Pitfall 1: Seconds vs. Milliseconds Confusion
Problem:
const timestamp = 1704067200; // Seconds
const date = new Date(timestamp); // Expects milliseconds!
console.log(date);
// Output: 1970-01-20 (WRONG!)
Solution:
const timestamp = 1704067200;
const date = new Date(timestamp * 1000); // Correct!
Pitfall 2: The Year 2038 Problem (Yes, It's Real)
Problem: Remember Y2K? Well, we've got another date-related disaster brewing. On January 19, 2038, at 03:14:07 UTC, every system using 32-bit signed integers for timestamps will overflow and wrap back to 1901. I'm not kidding – your toaster's firmware might think it's the Victorian era.
Solution: Thankfully, this one's easy – just use 64-bit integers. Most modern stuff already does:
- JavaScript? You're safe. It uses 64-bit floats that'll work until year 275,760 (by which point we'll probably have bigger problems)
- Python 3? No worries. Unlimited integer precision means it can count until the heat death of the universe
- Your database? Make sure you're using BIGINT (64-bit) instead of INT (32-bit)
Pitfall 3: Timezone Display Confusion
Problem:
const timestamp = 1704067200; // Jan 1, 2024, 00:00 UTC
const date = new Date(timestamp * 1000);
console.log(date.toString());
// Output: "Sun Dec 31 2023 16:00:00 GMT-0800 (PST)"
// Looks like Dec 31, 2023 in your timezone!
Solution: Always specify timezone when displaying:
console.log(date.toISOString()); // Always UTC
// Output: "2024-01-01T00:00:00.000Z"
console.log(date.toLocaleString('en-US', { timeZone: 'America/New_York' }));
// Output: "12/31/2023, 7:00:00 PM"
Pitfall 4: Floating Point Timestamps
Problem: Some systems use float timestamps with fractional seconds.
Solution: Round or floor to integer before storage:
const preciseTim timestamp = Date.now() / 1000; // 1704067200.537
const cleanTimestamp = Math.floor(preciseTimestamp); // 1704067200
Best Practices
1. Store in UTC, Display in Local
Always store Unix timestamps (which are UTC). Convert to local timezone only for display.
// Storage: Use Unix timestamp
const storedValue = Math.floor(Date.now() / 1000);
// Display: Convert to user's timezone
const displayValue = new Date(storedValue * 1000).toLocaleString('en-US', {
timeZone: userTimezone,
dateStyle: 'full',
timeStyle: 'short'
});
2. Use Appropriate Precision
- Seconds: Sufficient for most applications (events, logs, scheduling)
- Milliseconds: Needed for performance monitoring, rate limiting
- Microseconds/Nanoseconds: Required for high-frequency trading, scientific computing
3. Document Your Format
Always clarify in API docs and code comments:
/**
* @param {number} createdAt - Unix timestamp in seconds
* @returns {string} ISO 8601 date string
*/
function formatDate(createdAt) {
return new Date(createdAt * 1000).toISOString();
}
4. Validate Timestamps
Check for reasonable ranges:
function isValidTimestamp(timestamp) {
// After Jan 1, 2000 and before Jan 1, 2100
return timestamp >= 946684800 && timestamp <= 4102444800;
}
5. Use Libraries for Complex Operations
For timezone conversions, DST handling, and date arithmetic, use battle-tested libraries:
- JavaScript: Luxon, date-fns
- Python: pendulum, python-dateutil
- Java: java.time (built-in)
- PHP: Carbon
- Ruby: ActiveSupport::TimeZone
Real-World Use Cases
API Timestamps
// GraphQL schema
type Post {
id: ID!
title: String!
createdAt: Int! # Unix timestamp in seconds
updatedAt: Int!
}
// REST API response
{
"id": "post-123",
"title": "Hello World",
"created_at": 1704067200,
"updated_at": 1704070800
}
Database Storage
CREATE TABLE events (
id BIGINT PRIMARY KEY,
name VARCHAR(255),
occurred_at BIGINT NOT NULL, -- Unix timestamp
INDEX idx_occurred_at (occurred_at)
);
-- Query recent events
SELECT * FROM events
WHERE occurred_at > UNIX_TIMESTAMP(NOW() - INTERVAL 1 DAY)
ORDER BY occurred_at DESC;
Log Analysis
// Parse log timestamp
const logLine = "2024-01-01 00:00:00 | INFO | Server started";
const timestamp = new Date(logLine.split(' | ')[0]).getTime() / 1000;
// Find logs in time range
const startTime = 1704067200; // Jan 1, 2024, 00:00 UTC
const endTime = startTime + 86400; // 24 hours later
const filteredLogs = logs.filter(log =>
log.timestamp >= startTime && log.timestamp < endTime
);
Rate Limiting
const MAX_REQUESTS = 100;
const WINDOW_SECONDS = 3600; // 1 hour
function checkRateLimit(userId) {
const now = Math.floor(Date.now() / 1000);
const windowStart = now - WINDOW_SECONDS;
// Count requests in current window
const recentRequests = requests.filter(req =>
req.userId === userId && req.timestamp >= windowStart
);
return recentRequests.length < MAX_REQUESTS;
}
Advanced Topics
Leap Seconds
Unix time ignores leap seconds. When a leap second occurs, the same Unix timestamp may represent two different actual seconds. This is usually acceptable for most applications, but critical systems (GPS, astronomy) need special handling.
Sub-second Precision
For microsecond or nanosecond precision:
JavaScript:
// Performance timing (microseconds)
const start = performance.now();
// ... code execution ...
const duration = performance.now() - start;
console.log(`Execution took ${duration}ms`);
Python:
import time
# Nanoseconds (Python 3.7+)
timestamp = time.time_ns()
print(f"Nanoseconds since epoch: {timestamp}")
Working with Negative Timestamps
Timestamps before the Unix epoch are negative:
const date = new Date('1969-07-20T20:17:00Z'); // Moon landing
const timestamp = Math.floor(date.getTime() / 1000);
console.log(timestamp);
// Output: -14159020 (negative!)
Tools and Resources
Online Converters
- Timestamp Generator - Convert timestamps with timezone support
- EpochConverter.com - Simple Unix time converter
- Timestamp.fr - Visual timeline tool
Command Line
# Current Unix timestamp
date +%s
# Convert timestamp to date
date -d @1704067200
# Convert date to timestamp
date -d "2024-01-01 00:00:00 UTC" +%s
Browser Console
// Current timestamp (seconds)
Math.floor(Date.now() / 1000)
// Current timestamp (milliseconds)
Date.now()
// Convert any date
new Date('2024-01-01').getTime() / 1000
Wrapping Up
Look, I get it – timestamps aren't the most exciting topic in programming. But here's the thing: get this right, and you'll save yourself from so many headaches down the road. I've seen production systems go down because someone didn't understand the difference between seconds and milliseconds, or stored local time without timezone info.
The stuff you really need to remember:
- Unix timestamps are just seconds (or milliseconds) since January 1, 1970, UTC
- Always, always know if you're working with seconds or milliseconds
- Store everything in UTC, convert to local time only when displaying to users
- Pick the right precision for your use case (seconds for most things, milliseconds for performance tracking)
- Document your timestamp format in your API docs – your future self will thank you
- Don't try to handle complex date math yourself – use Luxon, date-fns, pendulum, or whatever library your language community recommends
Once you internalize these principles, handling time in your applications becomes almost second nature. And trust me, your users won't have to deal with meetings scheduled at 3 AM because of a timezone bug.
Further Reading
- ISO 8601 Standard Explained - Learn about the international date format standard
- Timezone Conversion Best Practices - Handle timezones correctly in your applications
- Working with Date-Time in JavaScript - Master JavaScript date handling patterns
- Common Timestamp Pitfalls - Avoid datetime bugs in production
- API Design: Timestamp Formats - Choose the right timestamp format for your API
Have questions or found this guide helpful? Contact us or share your feedback.