Unix Timestamp Pitfalls: A Complete Guide to Timestamp Conversion
Unix Timestamp Pitfalls: A Complete Guide to Timestamp Conversion#
Last week, I was debugging a production issue. The logs were filled with numbers like 1745678901. Our new intern looked confused: “What are these?” I said, “Unix timestamps.” He asked, “How do I convert them to human-readable time?”
That question made me realize timestamp conversion is trickier than I thought.
What is a Unix Timestamp?#
A Unix timestamp is the number of seconds since January 1, 1970, 00:00:00 UTC. Why 1970? That’s when Unix was born, and it needed a unified starting point.
// Get current timestamp (seconds)
const timestamp = Math.floor(Date.now() / 1000)
console.log(timestamp) // 1745678901
// Get current timestamp (milliseconds)
const ms = Date.now()
console.log(ms) // 1745678901234
JavaScript’s Date.now() returns milliseconds, but Unix timestamps are typically seconds. That’s the first pitfall.
Seconds vs Milliseconds: Auto-Detection#
Backend APIs might return timestamps in seconds or milliseconds. You need to detect which:
function normalizeTimestamp(ts: number): number {
// Seconds: 10 digits (1970-2286)
// Milliseconds: 13 digits (1970-5138)
if (ts > 9999999999) {
// Milliseconds, convert to seconds
return Math.floor(ts / 1000)
}
return ts
}
// Usage
console.log(normalizeTimestamp(1745678901)) // 1745678901 (seconds)
console.log(normalizeTimestamp(1745678901234)) // 1745678901 (converted)
The logic is simple: if it’s larger than 9999999999 (year 2286), it’s milliseconds.
Timestamp to Date: The Timezone Trap#
function timestampToDate(ts: number): string {
const normalized = normalizeTimestamp(ts)
const date = new Date(normalized * 1000)
// Local time
return date.toLocaleString('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
})
}
console.log(timestampToDate(1745678901))
// Output: 04/26/2025, 20:28:21 (Beijing time)
But here’s the problem: new Date() uses the local timezone. If your server is in Beijing and the user is in New York, the displayed time will be wrong.
Solution: Specify Timezone Explicitly#
function timestampToDateWithTimezone(ts: number, timezone: string): string {
const normalized = normalizeTimestamp(ts)
const date = new Date(normalized * 1000)
return date.toLocaleString('en-US', {
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
})
}
// Different timezones
console.log(timestampToDateWithTimezone(1745678901, 'Asia/Shanghai')) // 04/26/2025, 20:28:21
console.log(timestampToDateWithTimezone(1745678901, 'America/New_York')) // 04/26/2025, 08:28:21
console.log(timestampToDateWithTimezone(1745678901, 'UTC')) // 04/26/2025, 12:28:21
Date to Timestamp: String Format Pitfalls#
function dateToTimestamp(dateStr: string): number {
const date = new Date(dateStr)
if (isNaN(date.getTime())) {
throw new Error('Invalid date format')
}
return Math.floor(date.getTime() / 1000)
}
// Different formats
console.log(dateToTimestamp('2025-04-26 20:28:21')) // 1745678901 ✅
console.log(dateToTimestamp('2025/04/26 20:28:21')) // 1745678901 ✅
console.log(dateToTimestamp('2025-04-26T20:28:21')) // 1745678901 ✅ (ISO format)
console.log(dateToTimestamp('04/26/2025')) // Browser-dependent ⚠️
Use ISO 8601 format (YYYY-MM-DDTHH:mm:ss) — it’s the only format consistent across browsers.
Safer Approach: Manual Parsing#
function parseDateSafely(dateStr: string): number {
// Support: YYYY-MM-DD HH:mm:ss or YYYY-MM-DDTHH:mm:ss
const match = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})[T\s](\d{2}):(\d{2}):(\d{2})$/)
if (!match) {
throw new Error('Format must be YYYY-MM-DD HH:mm:ss')
}
const [, year, month, day, hour, minute, second] = match.map(Number)
const date = new Date(year, month - 1, day, hour, minute, second)
return Math.floor(date.getTime() / 1000)
}
console.log(parseDateSafely('2025-04-26 20:28:21')) // 1745678901 ✅
Common Timestamp Traps#
1. 32-bit Integer Overflow#
Legacy systems store timestamps as 32-bit signed integers. The maximum value is 2147483647, which corresponds to January 19, 2038. This is the famous “Year 2038 problem.”
// Problem on 32-bit systems
const max32bit = 2147483647
const date = new Date(max32bit * 1000)
console.log(date.toISOString()) // 2038-01-19T03:14:07.000Z
// Beyond this value, 32-bit systems wrap to negative
const overflow = 2147483648
// 32-bit: -2147483648 (year 1969)
// 64-bit: normal
2. Leap Seconds#
UTC occasionally inserts leap seconds, but Unix timestamps don’t account for them. This means some timestamps correspond to two different UTC times.
// 2016-12-31 23:59:60 UTC exists (leap second)
// But JavaScript's Date doesn't support it
const date = new Date('2016-12-31T23:59:60Z')
console.log(date) // Invalid Date
3. Browser Compatibility#
// Safari doesn't support YYYY-MM-DD HH:mm:ss format
const date1 = new Date('2025-04-26 20:28:21')
// Safari: Invalid Date ❌
// Chrome: Works ✅
// Solution: Replace space with T
const date2 = new Date('2025-04-26 20:28:21'.replace(' ', 'T'))
// Works in all browsers ✅
Performance Optimization for Batch Conversion#
When converting many timestamps, looping with new Date() can be slow:
// Batch conversion (slow)
function batchConvertSlow(timestamps: number[]): string[] {
return timestamps.map(ts => new Date(ts * 1000).toISOString())
}
// Batch conversion (fast)
function batchConvertFast(timestamps: number[]): string[] {
const results: string[] = new Array(timestamps.length)
for (let i = 0; i < timestamps.length; i++) {
const date = new Date(timestamps[i] * 1000)
results[i] = date.toISOString()
}
return results
}
// Performance: 1 million items
// batchConvertSlow: ~1200ms
// batchConvertFast: ~800ms
Pre-allocated array + for loop is about 30% faster than map.
A Practical Tool#
For daily use, I built an online tool: Timestamp Converter
Features:
- Real-time current timestamp display
- Auto-detection of seconds/milliseconds
- Multiple date format support
- One-click copy
The implementation isn’t complex, but getting the details right takes effort. Hope this helps.
Related: Timezone Converter | Date Calculator