Epoch Timestamps: Complete Developer Guide
Unix epoch timestamps are the universal language of time in computing. Understanding how to work with them effectively is essential for building robust applications that handle dates and times correctly across different systems and timezones.
What is an Epoch Timestamp?
A Unix epoch timestamp represents the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC (Coordinated Universal Time), not counting leap seconds.
Key Characteristics
- Zero Point: January 1, 1970, 00:00:00 UTC
- Unit: Seconds (or milliseconds in some systems)
- Timezone: Always UTC (timezone-independent)
- Format: Integer or floating-point number
- Range: 32-bit: 1901-2038, 64-bit: practically infinite
Why Use Epoch Timestamps?
1. Simplicity and Consistency
- Single number instead of complex date strings
- Easy to store, transmit, and compare
- No timezone confusion (always UTC)
2. Mathematical Operations
Timestamps enable easy date calculations:
// Calculate time differences const start = 1717000000; const end = 1717003600; const duration = end - start; // 3600 seconds (1 hour) // Add time intervals const now = Math.floor(Date.now() / 1000); const oneDayLater = now + (24 * 60 * 60); // Add 1 day const oneWeekLater = now + (7 * 24 * 60 * 60); // Add 1 week
3. Database Efficiency
- Integer storage uses less space than datetime strings
- Faster indexing and querying
- Standardized across database systems
Timestamp Formats
Seconds (Unix Time)
- Example: 1717000000
- Precision: 1 second
- Common in: Unix systems, APIs
- Year 2038 Problem: 32-bit overflow
Milliseconds (JavaScript)
- Example: 1717000000000
- Precision: 1 millisecond
- Common in: JavaScript, modern APIs
- No 2038 Problem: 64-bit by default
Working with Timestamps in Different Languages
1. JavaScript/TypeScript
// Current timestamp (milliseconds)
const nowMs = Date.now(); // 1717000000000
// Current timestamp (seconds)
const nowSeconds = Math.floor(Date.now() / 1000); // 1717000000
// Convert timestamp to Date object
const date = new Date(1717000000000);
console.log(date.toISOString()); // "2024-05-30T12:26:40.000Z"
// Convert Date to timestamp
const timestamp = date.getTime(); // 1717000000000
// Format timestamp
const formatted = new Date(1717000000000).toLocaleString('en-US', {
timeZone: 'America/New_York',
dateStyle: 'full',
timeStyle: 'long'
});
2. Python
import time
from datetime import datetime, timezone
# Current timestamp (seconds)
now_seconds = int(time.time()) # 1717000000
# Current timestamp (milliseconds)
now_ms = int(time.time() * 1000) # 1717000000000
# Convert timestamp to datetime
dt = datetime.fromtimestamp(1717000000, tz=timezone.utc)
print(dt.isoformat()) # "2024-05-30T12:26:40+00:00"
# Convert datetime to timestamp
timestamp = int(dt.timestamp()) # 1717000000
# Format with timezone
formatted = dt.strftime('%Y-%m-%d %H:%M:%S %Z')
3. SQL Databases
-- PostgreSQL
SELECT
EXTRACT(EPOCH FROM NOW()), -- Current timestamp in seconds
EXTRACT(EPOCH FROM NOW()) * 1000, -- In milliseconds
TO_TIMESTAMP(1717000000), -- Convert to timestamp
TO_CHAR(TO_TIMESTAMP(1717000000), 'YYYY-MM-DD HH24:MI:SS'); -- Format
-- MySQL
SELECT
UNIX_TIMESTAMP(), -- Current timestamp in seconds
UNIX_TIMESTAMP(NOW()) * 1000, -- In milliseconds
FROM_UNIXTIME(1717000000), -- Convert to datetime
DATE_FORMAT(FROM_UNIXTIME(1717000000), '%Y-%m-%d %H:%i:%s'); -- Format
Common Operations and Calculations
1. Time Difference Calculations
function formatDuration(seconds) {
const units = [
{ name: 'day', seconds: 86400 },
{ name: 'hour', seconds: 3600 },
{ name: 'minute', seconds: 60 },
{ name: 'second', seconds: 1 }
];
const parts = [];
let remaining = seconds;
for (const unit of units) {
const count = Math.floor(remaining / unit.seconds);
if (count > 0) {
parts.push(`${count} ${unit.name}${count !== 1 ? 's' : ''}`);
remaining %= unit.seconds;
}
}
return parts.length > 0 ? parts.join(', ') : '0 seconds';
}
// Example usage
const startTime = 1717000000;
const endTime = 1717007260; // 2 hours, 1 minute later
const duration = endTime - startTime; // 7260 seconds
console.log(formatDuration(duration)); // "2 hours, 1 minute"
2. Date Range Queries
// Get start and end of current day (in UTC)
function getTodayRange() {
const now = new Date();
const startOfDay = new Date(Date.UTC(
now.getUTCFullYear(),
now.getUTCMonth(),
now.getUTCDate()
));
const endOfDay = new Date(startOfDay);
endOfDay.setUTCDate(endOfDay.getUTCDate() + 1);
return {
start: Math.floor(startOfDay.getTime() / 1000),
end: Math.floor(endOfDay.getTime() / 1000) - 1
};
}
// Get last 7 days
function getLast7Days() {
const now = Math.floor(Date.now() / 1000);
const sevenDaysAgo = now - (7 * 24 * 60 * 60);
return { start: sevenDaysAgo, end: now };
}
// Database query example
const { start, end } = getTodayRange();
const query = `
SELECT * FROM events
WHERE timestamp >= ${start}
AND timestamp <= ${end}
ORDER BY timestamp DESC
`;
Timezone Handling
⚠️ Timezone Pitfalls
- ✗ Assuming Local Time: Timestamps are always UTC
- ✗ Daylight Saving Time: DST changes can break calculations
- ✗ Server Timezone: Don't rely on server's local time
- ✗ Browser Differences: Different browsers may handle timezones differently
Best Practices for Timezone Handling
// Always store and transmit in UTC
function storeTimestamp() {
const timestamp = Math.floor(Date.now() / 1000); // UTC seconds
// Store in database
db.insert({ event_time: timestamp });
}
// Convert to local time for display
function displayTimestamp(timestamp, timezone = 'UTC') {
const date = new Date(timestamp * 1000);
return date.toLocaleString('en-US', {
timeZone: timezone,
dateStyle: 'medium',
timeStyle: 'short'
});
}
// Handle user timezone
function getUserLocalTime(timestamp) {
const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
return displayTimestamp(timestamp, userTimezone);
}
// Example: Display event time in user's local timezone
const eventTimestamp = 1717000000;
const localTime = getUserLocalTime(eventTimestamp);
console.log(`Event time: ${localTime}`);
The Year 2038 Problem
32-bit systems will overflow on January 19, 2038 when the timestamp exceeds 2,147,483,647 seconds.
2038 Problem Solutions
✅ Use 64-bit Timestamps
- Milliseconds since epoch
- No overflow for billions of years
- Standard in modern systems
⚠️ Legacy Systems
- Update to 64-bit where possible
- Use datetime strings as fallback
- Plan migration before 2038
Best Practices
✅ Epoch Timestamp Best Practices
- ✓ Always use UTC - Store and transmit timestamps in UTC
- ✓ Use milliseconds for precision - JavaScript-style timestamps
- ✓ Validate timestamps - Check for reasonable ranges
- ✓ Handle timezones at display layer - Convert UTC to local time only for UI
-
✓
Use ISO 8601 for APIs - Consider
2024-05-30T12:26:40Zformat - ✓ Test across timezones - Ensure consistent behavior worldwide
Testing with Our Epoch Tool
Use our Epoch Converter Tool to:
- Convert between timestamps and human-readable dates
- Test different timestamp formats (seconds vs milliseconds)
- Compare timezone conversions
- Calculate date differences
- Learn through practical examples
Real-World Examples
1. API Rate Limiting
class RateLimiter {
constructor(limit, windowSeconds) {
this.limit = limit;
this.window = windowSeconds;
this.requests = new Map(); // user_id -> timestamp[]
}
isAllowed(userId) {
const now = Math.floor(Date.now() / 1000);
const windowStart = now - this.window;
// Get user's recent requests
let userRequests = this.requests.get(userId) || [];
// Filter out old requests
userRequests = userRequests.filter(time => time > windowStart);
// Check if under limit
if (userRequests.length >= this.limit) {
return false;
}
// Add current request
userRequests.push(now);
this.requests.set(userId, userRequests);
return true;
}
}
// Usage: 100 requests per hour
const limiter = new RateLimiter(100, 3600);
const canProceed = limiter.isAllowed('user123');
2. Cache Expiration
class Cache {
constructor() {
this.store = new Map(); // key -> { value, expires }
}
set(key, value, ttlSeconds) {
const expires = Math.floor(Date.now() / 1000) + ttlSeconds;
this.store.set(key, { value, expires });
}
get(key) {
const entry = this.store.get(key);
if (!entry) return null;
const now = Math.floor(Date.now() / 1000);
if (now > entry.expires) {
this.store.delete(key);
return null;
}
return entry.value;
}
cleanup() {
const now = Math.floor(Date.now() / 1000);
for (const [key, entry] of this.store.entries()) {
if (now > entry.expires) {
this.store.delete(key);
}
}
}
}
// Usage: Cache with 5-minute TTL
const cache = new Cache();
cache.set('user:123', { name: 'John' }, 300); // 5 minutes
const user = cache.get('user:123');
Conclusion
Epoch timestamps provide a simple, efficient, and standardized way to work with time in software applications. By following best practices—storing in UTC, using appropriate precision, and handling timezones correctly—you can avoid common pitfalls and build robust time-handling functionality.
Remember that while timestamps are great for storage and calculations, consider using ISO 8601 strings for API responses to improve readability and interoperability.