Home/Blog/Unix Timestamp: Seconds vs Milliseconds - What
Web Development

Unix Timestamp: Seconds vs Milliseconds - What

Understand the critical difference between Unix timestamps in seconds and milliseconds, why JavaScript uses milliseconds, and how to convert between formats correctly.

By Inventive HQ Team
Unix Timestamp: Seconds vs Milliseconds - What

The Critical Difference Between Seconds and Milliseconds

One of the most common sources of bugs in time-related code is the confusion between Unix timestamps measured in seconds versus milliseconds. While both represent time elapsed since the Unix Epoch (January 1, 1970 UTC), they differ by a factor of 1,000—and mixing them up can cause your dates to appear decades off or events to seem instantaneous.

Let's break down this crucial distinction and learn how to handle timestamp conversions correctly across different programming environments.

Understanding the Two Formats

Unix Timestamp in Seconds (10 digits)

The traditional Unix timestamp format counts seconds since the epoch and typically contains 10 digits (as of 2025).

Example: 1735689600

This represents January 1, 2025, 00:00:00 UTC.

Where it's used:

  • Unix/Linux system time (date +%s)
  • PHP (time(), strtotime())
  • Python (time.time())
  • Ruby (Time.now.to_i)
  • Most SQL databases (UNIX_TIMESTAMP() in MySQL)
  • Server logs and system events
  • Most RESTful APIs (especially backend systems)

Unix Timestamp in Milliseconds (13 digits)

The milliseconds format counts milliseconds since the epoch and contains 13 digits.

Example: 1735689600000

This represents the exact same moment: January 1, 2025, 00:00:00 UTC.

Where it's used:

  • JavaScript (Date.now(), new Date().getTime())
  • Java (System.currentTimeMillis())
  • Node.js (inherits JavaScript behavior)
  • Some modern APIs that require sub-second precision
  • High-frequency trading systems
  • Performance monitoring and profiling

Why JavaScript Uses Milliseconds

JavaScript's decision to use milliseconds has historical roots. When Brendan Eich created JavaScript in 1995, he modeled the Date object after Java's java.util.Date class, which used milliseconds for finer precision.

This choice has both advantages and drawbacks:

Advantages of Milliseconds

Sub-second precision: Milliseconds allow you to measure events that happen faster than one second:

const start = Date.now(); // 1735689600000
// ... some operation ...
const end = Date.now();   // 1735689600123
const duration = end - start; // 123 milliseconds

Animation and timing: When building user interfaces, milliseconds matter:

// Request animation frame timing
function animate(timestamp) {
  // timestamp is in milliseconds
  const progress = (timestamp - animationStart) / 1000;
  // Convert to seconds for calculations
}

Event logging: Modern web analytics and performance monitoring need millisecond precision:

// Tracking page load performance
const pageLoadTime = performance.timing.loadEventEnd -
                     performance.timing.navigationStart;

The Compatibility Challenge

The millisecond format creates friction when JavaScript applications communicate with backend systems that use seconds:

// Frontend sends timestamp to backend
fetch('/api/save', {
  method: 'POST',
  body: JSON.stringify({
    timestamp: Date.now() // ❌ 1735689600000 (milliseconds)
  })
});

// Backend (PHP) receives it
$timestamp = $_POST['timestamp']; // 1735689600000
$date = date('Y-m-d', $timestamp); // ❌ Year 56970!

This is one of the most common bugs in web development.

Converting Between Seconds and Milliseconds

Milliseconds to Seconds

To convert from JavaScript milliseconds to Unix seconds:

// Method 1: Division with Math.floor
const seconds = Math.floor(Date.now() / 1000);

// Method 2: Integer division with bitwise OR (faster)
const seconds = (Date.now() / 1000) | 0;

// Method 3: Using Math.trunc (clearer intent)
const seconds = Math.trunc(Date.now() / 1000);

Important: Always use Math.floor() or integer conversion, not just division:

// ❌ WRONG: Creates decimal number
const seconds = Date.now() / 1000; // 1735689600.123

// ✅ CORRECT: Integer seconds
const seconds = Math.floor(Date.now() / 1000); // 1735689600

Seconds to Milliseconds

Converting seconds to milliseconds is simpler—just multiply by 1,000:

// Backend returns seconds
const secondsFromAPI = 1735689600;

// Convert to milliseconds for JavaScript Date
const date = new Date(secondsFromAPI * 1000);

console.log(date); // 2025-01-01T00:00:00.000Z

Detecting the Format Automatically

How can you tell if a timestamp is in seconds or milliseconds? Here's a reliable heuristic:

function detectTimestampFormat(timestamp) {
  // Count digits
  const digits = timestamp.toString().length;

  if (digits === 10) {
    return 'seconds';
  } else if (digits === 13) {
    return 'milliseconds';
  } else {
    throw new Error('Invalid timestamp format');
  }
}

// Or check against a known date
function isMilliseconds(timestamp) {
  // Anything after year 2286 as seconds would be
  // more than 10 trillion as milliseconds
  return timestamp > 10000000000;
}

Smart conversion function:

function toJavaScriptDate(timestamp) {
  // If it looks like seconds, convert to milliseconds
  if (timestamp < 10000000000) {
    return new Date(timestamp * 1000);
  }
  // Otherwise, assume milliseconds
  return new Date(timestamp);
}

Common Pitfalls and How to Avoid Them

Pitfall 1: Double Conversion

// Backend API returns seconds
const apiResponse = { created_at: 1735689600 };

// ❌ WRONG: Already in seconds, don't convert again
const date1 = new Date(apiResponse.created_at / 1000);
// Results in 1970-01-21

// ✅ CORRECT: Convert seconds to milliseconds
const date2 = new Date(apiResponse.created_at * 1000);
// Results in 2025-01-01

Pitfall 2: Forgetting to Convert

// Receiving Unix seconds from backend
const unixSeconds = 1735689600;

// ❌ WRONG: JavaScript Date expects milliseconds
const date = new Date(unixSeconds);
console.log(date); // 1970-01-21 (way off!)

// ✅ CORRECT: Multiply by 1000
const date = new Date(unixSeconds * 1000);
console.log(date); // 2025-01-01 (correct!)

Pitfall 3: Mixing Formats in Calculations

// ❌ WRONG: Mixing seconds and milliseconds
const serverTime = 1735689600; // seconds from API
const clientTime = Date.now();  // milliseconds
const diff = clientTime - serverTime; // meaningless number!

// ✅ CORRECT: Convert to same format first
const serverTimeMs = serverTime * 1000;
const diff = clientTime - serverTimeMs; // milliseconds difference

Pitfall 4: Database Timestamp Columns

When storing JavaScript timestamps in SQL databases:

// ❌ WRONG: Storing milliseconds where seconds expected
db.query(
  'INSERT INTO events (timestamp) VALUES (?)',
  [Date.now()] // 1735689600000
);

// ✅ CORRECT: Convert to seconds for database
db.query(
  'INSERT INTO events (timestamp) VALUES (?)',
  [Math.floor(Date.now() / 1000)] // 1735689600
);

Best Practices for Full-Stack Applications

1. Document Your API Clearly

In your API documentation, always specify the timestamp format:

/**
 * @api {post} /events Create Event
 * @apiParam {Number} timestamp Unix timestamp in SECONDS
 * @apiSuccess {Object} event Created event
 * @apiSuccess {Number} event.created_at Unix timestamp in SECONDS
 */

2. Use Consistent Format in APIs

Choose one format for your API and stick with it:

// ✅ GOOD: API always uses seconds
app.get('/api/events', (req, res) => {
  res.json({
    events: events.map(e => ({
      id: e.id,
      name: e.name,
      created_at: Math.floor(e.created_at / 1000) // Always seconds
    }))
  });
});

3. Create Conversion Utilities

Build reusable conversion functions:

// utils/time.js
export const toUnixSeconds = (date = new Date()) => {
  return Math.floor(date.getTime() / 1000);
};

export const fromUnixSeconds = (seconds) => {
  return new Date(seconds * 1000);
};

export const toUnixMilliseconds = (date = new Date()) => {
  return date.getTime();
};

export const fromUnixMilliseconds = (milliseconds) => {
  return new Date(milliseconds);
};

4. Validate Timestamp Format

Add validation to catch errors early:

function validateUnixTimestamp(timestamp, format = 'seconds') {
  const now = Date.now() / 1000; // Current time in seconds
  const minDate = 0; // Unix epoch
  const maxDate = now + (100 * 365 * 24 * 60 * 60); // 100 years in future

  if (format === 'seconds') {
    if (timestamp < minDate || timestamp > maxDate) {
      throw new Error('Invalid Unix timestamp (seconds)');
    }
  } else if (format === 'milliseconds') {
    const timestampSeconds = timestamp / 1000;
    if (timestampSeconds < minDate || timestampSeconds > maxDate) {
      throw new Error('Invalid Unix timestamp (milliseconds)');
    }
  }

  return true;
}

Language-Specific Examples

Python (seconds) to JavaScript (milliseconds)

# Python backend
import time
timestamp = int(time.time())  # 1735689600 (seconds)

# Send to frontend
return jsonify({'timestamp': timestamp})
// JavaScript frontend
fetch('/api/time')
  .then(r => r.json())
  .then(data => {
    const date = new Date(data.timestamp * 1000); // Convert to ms
    console.log(date);
  });

JavaScript (milliseconds) to PHP (seconds)

// JavaScript frontend
const timestamp = Date.now(); // 1735689600000 (milliseconds)

fetch('/api/save', {
  method: 'POST',
  body: JSON.stringify({
    timestamp: Math.floor(timestamp / 1000) // Convert to seconds
  })
});
// PHP backend
$timestamp = $_POST['timestamp']; // 1735689600 (seconds)
$date = date('Y-m-d H:i:s', $timestamp);

Conclusion

The difference between Unix timestamps in seconds and milliseconds is one of the most important distinctions in cross-platform time handling. Remember these key points:

  1. Seconds (10 digits) are used by most backend systems, databases, and Unix tools
  2. Milliseconds (13 digits) are used by JavaScript, Java, and some modern APIs
  3. Always convert explicitly when crossing language boundaries
  4. Document your API format clearly to prevent confusion
  5. Use digit count or magnitude checks to detect format automatically when needed

By understanding and properly handling these formats, you'll avoid one of the most common categories of bugs in web development and ensure your applications handle time correctly across all platforms.

Need to convert between Unix timestamp formats? Try our Unix Timestamp Converter for instant, accurate conversions with timezone support.

Need Expert IT & Security Guidance?

Our team is ready to help protect and optimize your business technology infrastructure.