Guides
Timestamp Precision Levels: Seconds, Milliseconds, Microseconds & Nanoseconds Explained
Understanding Timestamp Precision
Timestamp precision refers to the level of detail at which a timestamp measures time. Different applications require different levels of precision, from basic second-level accuracy to ultra-precise nanosecond measurements. Understanding these precision levels is crucial for choosing the right format for your use case.
The four main precision levels are:
- Seconds (10 digits) - Standard Unix timestamp
- Milliseconds (13 digits) - JavaScript, Java default
- Microseconds (16 digits) - High-precision systems
- Nanoseconds (19 digits) - Ultra-precise timing
The Four Precision Levels
1. Seconds (10 Digits)
Standard Unix Timestamp - The original and most common format.
Format
Example: 1704067200
Represents: January 1, 2024, 00:00:00 UTC
Precision: 1 second
Digit Count: 10 digits
Characteristics
- Range: December 13, 1901 to January 19, 2038 (32-bit signed)
- Range: September 21, 1677 to December 4, 292,277,026,596 (64-bit signed)
- Storage: 4 bytes (32-bit) or 8 bytes (64-bit)
- Accuracy: ±0.5 seconds
When to Use
- ✅ Event logging (user registration, login times)
- ✅ Database timestamps (created_at, updated_at)
- ✅ File modification times
- ✅ Scheduling tasks (cron jobs, batch processes)
- ✅ General timestamping where sub-second precision isn't needed
Code Examples
C/C++
c
#include <time.h>
#include <stdio.h>
int main() {
time_t timestamp = time(NULL);
printf("Current timestamp: %ld\n", timestamp);
// Output: 1704067200 (10 digits)
return 0;
}
Python
import time
timestamp = int(time.time())
print(f"Current timestamp: {timestamp}")
# Output: 1704067200 (10 digits)
PHP
<?php
$timestamp = time();
echo "Current timestamp: $timestamp\n";
// Output: 1704067200 (10 digits)
?>
SQL
-- Most databases store TIMESTAMP with second precision
SELECT UNIX_TIMESTAMP();
-- Output: 1704067200
2. Milliseconds (13 Digits)
JavaScript/Java Standard - Adds three decimal places for millisecond precision.
Format
Example: 1704067200000
Represents: January 1, 2024, 00:00:00.000 UTC
Precision: 0.001 seconds (1 millisecond)
Digit Count: 13 digits
Characteristics
- Range: ±8,640,000,000,000,000 milliseconds from epoch
- Storage: 8 bytes (64-bit integer or double)
- Accuracy: ±0.0005 seconds (0.5 milliseconds)
- Resolution: 1/1,000th of a second
When to Use
- ✅ Web applications (JavaScript Date.now())
- ✅ Performance monitoring (API response times)
- ✅ Animation timing (frame rates, transitions)
- ✅ Event tracking (click times, user interactions)
- ✅ Trading systems (stock prices, order execution)
- ✅ Real-time communications (chat applications)
Code Examples
JavaScript
// Get current timestamp in milliseconds
const timestamp = Date.now();
console.log(timestamp);
// Output: 1704067200000 (13 digits)
// Create Date from millisecond timestamp
const date = new Date(1704067200000);
console.log(date.toISOString());
// Output: 2024-01-01T00:00:00.000Z
Java
// Get current timestamp in milliseconds
long timestamp = System.currentTimeMillis();
System.out.println(timestamp);
// Output: 1704067200000 (13 digits)
// Create Date from millisecond timestamp
Date date = new Date(1704067200000L);
System.out.println(date);
Python
import time
# Get timestamp in milliseconds
timestamp_ms = int(time.time() * 1000)
print(f"Millisecond timestamp: {timestamp_ms}")
# Output: 1704067200000 (13 digits)
Node.js
// High-resolution time in milliseconds
const start = performance.now();
// ... some operation ...
const end = performance.now();
console.log(`Operation took ${end - start} milliseconds`);
3. Microseconds (16 Digits)
High-Precision Systems - Six decimal places for microsecond precision.
Format
Example: 1704067200000000
Represents: January 1, 2024, 00:00:00.000000 UTC
Precision: 0.000001 seconds (1 microsecond)
Digit Count: 16 digits
Characteristics
- Range: Extremely wide (±292,471 years from epoch)
- Storage: 8 bytes (64-bit integer)
- Accuracy: ±0.0000005 seconds (0.5 microseconds)
- Resolution: 1/1,000,000th of a second
When to Use
- ✅ Database systems (PostgreSQL, MongoDB)
- ✅ Scientific computing (physics simulations)
- ✅ Network protocols (packet timestamping)
- ✅ Audio/video processing (frame synchronization)
- ✅ High-frequency trading (microsecond-level execution)
- ✅ Distributed systems (event ordering, causality)
Code Examples
Python
import time
# Get timestamp in microseconds
timestamp_us = int(time.time() * 1_000_000)
print(f"Microsecond timestamp: {timestamp_us}")
# Output: 1704067200000000 (16 digits)
# Using datetime
from datetime import datetime
dt = datetime.now()
timestamp_us = int(dt.timestamp() * 1_000_000)
print(f"Microsecond timestamp: {timestamp_us}")
Go
package main
import (
"fmt"
"time"
)
func main() {
// Get current timestamp in microseconds
timestamp := time.Now().UnixMicro()
fmt.Printf("Microsecond timestamp: %d\n", timestamp)
// Output: 1704067200000000 (16 digits)
}
PostgreSQL
-- PostgreSQL stores timestamps with microsecond precision
SELECT EXTRACT(EPOCH FROM NOW()) * 1000000;
-- Output: 1704067200000000
-- Create timestamp with microsecond precision
SELECT to_timestamp(1704067200.123456);
-- Output: 2024-01-01 00:00:00.123456+00
C++
#include <chrono>
#include <iostream>
int main() {
using namespace std::chrono;
// Get microsecond timestamp
auto now = system_clock::now();
auto micros = duration_cast<microseconds>(
now.time_since_epoch()
).count();
std::cout << "Microsecond timestamp: " << micros << std::endl;
// Output: 1704067200000000 (16 digits)
return 0;
}
4. Nanoseconds (19 Digits)
Ultra-Precise Timing - Nine decimal places for nanosecond precision.
Format
Example: 1704067200000000000
Represents: January 1, 2024, 00:00:00.000000000 UTC
Precision: 0.000000001 seconds (1 nanosecond)
Digit Count: 19 digits
Characteristics
- Range: ±292 years from epoch (64-bit signed)
- Storage: 8 bytes (64-bit integer)
- Accuracy: ±0.0000000005 seconds (0.5 nanoseconds)
- Resolution: 1/1,000,000,000th of a second
When to Use
- ✅ Performance profiling (CPU cycle measurements)
- ✅ Hardware instrumentation (oscilloscopes, logic analyzers)
- ✅ Kernel development (scheduler timestamps)
- ✅ Real-time systems (robotics, aerospace)
- ✅ Cryptographic timestamping (blockchain, security)
- ✅ Physics experiments (particle detection)
Code Examples
Go
package main
import (
"fmt"
"time"
)
func main() {
// Get current timestamp in nanoseconds
timestamp := time.Now().UnixNano()
fmt.Printf("Nanosecond timestamp: %d\n", timestamp)
// Output: 1704067200000000000 (19 digits)
// Benchmark operations
start := time.Now()
// ... some operation ...
elapsed := time.Since(start).Nanoseconds()
fmt.Printf("Operation took %d nanoseconds\n", elapsed)
}
Rust
use std::time::{SystemTime, UNIX_EPOCH};
fn main() {
// Get nanosecond timestamp
let duration = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap();
let nanos = duration.as_nanos();
println!("Nanosecond timestamp: {}", nanos);
// Output: 1704067200000000000 (19 digits)
}
C++
#include <chrono>
#include <iostream>
int main() {
using namespace std::chrono;
// Get nanosecond timestamp
auto now = system_clock::now();
auto nanos = duration_cast<nanoseconds>(
now.time_since_epoch()
).count();
std::cout << "Nanosecond timestamp: " << nanos << std::endl;
// Output: 1704067200000000000 (19 digits)
return 0;
}
Linux (C)
c
#include <time.h>
#include <stdio.h>
int main() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
long long nanos = (long long)ts.tv_sec * 1000000000LL + ts.tv_nsec;
printf("Nanosecond timestamp: %lld\n", nanos);
// Output: 1704067200000000000 (19 digits)
return 0;
}
Precision Comparison Table
| Level | Precision | Digits | Example | Use Cases | Languages/Systems |
|---|---|---|---|---|---|
| Second | 1s | 10 | 1704067200 | Logs, databases, scheduling | C, PHP, Python, SQL |
| Millisecond | 1ms (10⁻³s) | 13 | 1704067200000 | Web apps, trading, APIs | JavaScript, Java |
| Microsecond | 1μs (10⁻⁶s) | 16 | 1704067200000000 | HFT, audio/video, networks | Python, Go, PostgreSQL |
| Nanosecond | 1ns (10⁻⁹s) | 19 | 1704067200000000000 | Profiling, hardware, crypto | Go, Rust, C++ |
Converting Between Precision Levels
Scaling Up (Adding Precision)
// Second to Millisecond
const seconds = 1704067200;
const milliseconds = seconds * 1000;
// 1704067200000
// Millisecond to Microsecond
const microseconds = milliseconds * 1000;
// 1704067200000000
// Microsecond to Nanosecond
const nanoseconds = microseconds * 1000;
// 1704067200000000000
Scaling Down (Reducing Precision)
// Nanosecond to Microsecond
const nanos = 1704067200123456789;
const micros = Math.floor(nanos / 1000);
// 1704067200123456
// Microsecond to Millisecond
const millis = Math.floor(micros / 1000);
// 1704067200123
// Millisecond to Second
const secs = Math.floor(millis / 1000);
// 1704067200
Python Conversion Utility
class TimestampConverter:
"""Convert between different timestamp precision levels"""
@staticmethod
def to_milliseconds(timestamp, from_precision='seconds'):
"""Convert any precision to milliseconds"""
multipliers = {
'seconds': 1000,
'milliseconds': 1,
'microseconds': 0.001,
'nanoseconds': 0.000001
}
return int(timestamp * multipliers[from_precision])
@staticmethod
def to_microseconds(timestamp, from_precision='seconds'):
"""Convert any precision to microseconds"""
multipliers = {
'seconds': 1_000_000,
'milliseconds': 1000,
'microseconds': 1,
'nanoseconds': 0.001
}
return int(timestamp * multipliers[from_precision])
@staticmethod
def to_nanoseconds(timestamp, from_precision='seconds'):
"""Convert any precision to nanoseconds"""
multipliers = {
'seconds': 1_000_000_000,
'milliseconds': 1_000_000,
'microseconds': 1000,
'nanoseconds': 1
}
return int(timestamp * multipliers[from_precision])
# Usage
converter = TimestampConverter()
# Convert 1704067200 seconds to milliseconds
ms = converter.to_milliseconds(1704067200, 'seconds')
print(ms) # 1704067200000
Performance Considerations
Storage Requirements
| Precision | 32-bit | 64-bit | Database Storage |
|---|---|---|---|
| Seconds | 4 bytes | 8 bytes | TIMESTAMP (4-8 bytes) |
| Milliseconds | ❌ Overflow | 8 bytes | BIGINT (8 bytes) |
| Microseconds | ❌ Overflow | 8 bytes | BIGINT (8 bytes) |
| Nanoseconds | ❌ Overflow | 8 bytes | BIGINT (8 bytes) |
Processing Speed
// Benchmark: Different precision levels
const iterations = 1000000;
// Seconds (fastest)
console.time('Seconds');
for (let i = 0; i < iterations; i++) {
const ts = Math.floor(Date.now() / 1000);
}
console.timeEnd('Seconds');
// ~10ms
// Milliseconds (fast)
console.time('Milliseconds');
for (let i = 0; i < iterations; i++) {
const ts = Date.now();
}
console.timeEnd('Milliseconds');
// ~12ms
// Microseconds (slower)
console.time('Microseconds');
for (let i = 0; i < iterations; i++) {
const ts = performance.now() * 1000;
}
console.timeEnd('Microseconds');
// ~25ms
Memory Impact
import sys
# Storage comparison
second_ts = 1704067200
millisecond_ts = 1704067200000
microsecond_ts = 1704067200000000
nanosecond_ts = 1704067200000000000
print(f"Second: {sys.getsizeof(second_ts)} bytes") # 28 bytes
print(f"Millisecond: {sys.getsizeof(millisecond_ts)} bytes") # 28 bytes
print(f"Microsecond: {sys.getsizeof(microsecond_ts)} bytes") # 28 bytes
print(f"Nanosecond: {sys.getsizeof(nanosecond_ts)} bytes") # 32 bytes
# In arrays/databases, smaller integers = better performance
Accuracy vs. Precision
Understanding the Difference
- Precision: How finely you can measure (the number of digits)
- Accuracy: How close your measurement is to the true value
Example:
Precision: Nanosecond timestamp (19 digits)
Accuracy: System clock may only be accurate to ±50ms
Result: High precision, low accuracy
System Clock Limitations
| System | Typical Resolution | Accuracy |
|---|---|---|
| Windows | 15.6ms | ±10-50ms |
| Linux | 1μs - 1ms | ±1-10ms |
| macOS | 1μs | ±1-10ms |
| Real-Time OS | 1ns - 1μs | ±1μs |
Testing Your System's Resolution
import time
def measure_clock_resolution():
"""Measure actual system clock resolution"""
samples = []
prev = time.time()
for _ in range(100000):
current = time.time()
if current != prev:
samples.append(current - prev)
prev = current
if samples:
min_diff = min(samples)
print(f"Minimum time difference: {min_diff * 1000:.6f}ms")
print(f"Approximate resolution: {min_diff * 1_000_000:.2f}μs")
measure_clock_resolution()
Best Practices
1. Choose Appropriate Precision
# ✅ GOOD: Match precision to use case
user_login_time = int(time.time()) # Seconds are enough
# ❌ BAD: Unnecessary precision
user_login_time = int(time.time() * 1_000_000_000) # Overkill!
2. Store Consistently
-- ✅ GOOD: Consistent precision across table
CREATE TABLE events (
id BIGINT PRIMARY KEY,
created_at BIGINT, -- All in milliseconds
updated_at BIGINT -- All in milliseconds
);
-- ❌ BAD: Mixed precision
CREATE TABLE events (
id BIGINT PRIMARY KEY,
created_at INT, -- Seconds
updated_at BIGINT -- Milliseconds (inconsistent!)
);
3. Document Your Choice
/**
* Timestamp precision: Milliseconds (13 digits)
* Format: Unix timestamp * 1000
* Example: 1704067200000 = Jan 1, 2024 00:00:00.000 UTC
*/
const timestamp = Date.now();
4. Handle Conversion Carefully
# ✅ GOOD: Explicit conversion
def seconds_to_milliseconds(seconds):
"""Convert seconds to milliseconds"""
return int(seconds * 1000)
# ❌ BAD: Implicit/unclear
def convert(ts):
return ts * 1000 # What precision is this?
5. Validate Precision
function validateTimestamp(timestamp, expectedPrecision) {
const digitCount = timestamp.toString().length;
const expectedDigits = {
'seconds': 10,
'milliseconds': 13,
'microseconds': 16,
'nanoseconds': 19
};
if (digitCount !== expectedDigits[expectedPrecision]) {
throw new Error(
`Invalid ${expectedPrecision} timestamp: expected ${expectedDigits[expectedPrecision]} digits, got ${digitCount}`
);
}
return true;
}
// Usage
validateTimestamp(1704067200000, 'milliseconds'); // ✅ Pass
validateTimestamp(1704067200, 'milliseconds'); // ❌ Error
Common Pitfalls
1. Precision Loss in Floating Point
// ❌ BAD: JavaScript Number precision limit
const nanos = 1704067200123456789; // 19 digits
console.log(nanos);
// Output: 1704067200123456800 (last digits lost!)
// ✅ GOOD: Use BigInt for nanoseconds
const nanos = 1704067200123456789n;
console.log(nanos.toString());
// Output: 1704067200123456789 (exact)
2. Timezone Confusion
# ❌ BAD: Local time affects precision
import datetime
local_time = datetime.datetime.now() # Includes local timezone
timestamp = local_time.timestamp()
# ✅ GOOD: Always use UTC
utc_time = datetime.datetime.utcnow()
timestamp = utc_time.timestamp()
3. Overflow Issues
c
// ❌ BAD: 32-bit overflow with milliseconds
int32_t timestamp_ms = time(NULL) * 1000; // Overflow!
// ✅ GOOD: Use 64-bit for higher precision
int64_t timestamp_ms = (int64_t)time(NULL) * 1000;
Related Tools
Use our free tools to work with different timestamp precisions:
- Unix Timestamp Converter - Convert between precision levels
- Batch Timestamp Converter - Convert multiple timestamps
- Timestamp Format Builder - Create custom formats
- Current Timestamp - Get timestamps in all precisions
Conclusion
Understanding timestamp precision levels is essential for modern software development. Choose the right precision level based on your specific requirements:
- Seconds: General-purpose timestamping, logs, databases
- Milliseconds: Web applications, APIs, real-time features
- Microseconds: High-frequency trading, scientific computing
- Nanoseconds: Performance profiling, hardware instrumentation
Remember:
- Higher precision = More storage + More processing
- Match precision to actual system accuracy
- Be consistent across your application
- Document your choice for future developers
Last updated: January 2025