Guides
Understanding Timestamp Formats
Introduction
Timestamps come in various formats and precisions. Understanding these formats is crucial for developers working with time data, APIs, databases, and distributed systems.
Quick Summary: Unix timestamps (seconds, milliseconds, microseconds, nanoseconds), ISO 8601 strings, and RFC 3339 formats are the most common. Each serves different purposes in software development.
Unix Timestamp Formats
Unix Epoch (POSIX Time)
Unix timestamp represents time as number of seconds/milliseconds since January 1, 1970, 00:00:00 UTC.
Unix Epoch Reference:
Start Date: January 1, 1970, 00:00:00 UTC
Current: January 1, 2026, 00:00:00 UTC
Timestamp: 1735689600 (seconds)
Precision Levels
| Precision | Example | Magnitude | Common Use |
|---|---|---|---|
| Seconds | 1735689600 | 10 digits | Unix/Linux systems |
| Milliseconds | 17356896000000 | 13 digits | JavaScript, Web APIs |
| Microseconds | 173568960000000000 | 16 digits | High-precision timing |
| Nanoseconds | 173568960000000000000 | 19 digits | Scientific computing |
Code Examples: Different Precisions
// JavaScript uses milliseconds by default
const msTimestamp = Date.now(); // 17356896000000
const secTimestamp = Math.floor(Date.now() / 1000); // 1735689600
const nsTimestamp = Date.now() * 1000000; // 173568960000000000000
console.log('Milliseconds:', msTimestamp);
console.log('Seconds:', secTimestamp);
console.log('Nanoseconds:', nsTimestamp);
from datetime import datetime
import time
# Python supports multiple precisions
now = datetime.now(datetime.timezone.utc)
sec_timestamp = int(now.timestamp())
ms_timestamp = int(now.timestamp() * 1000)
us_timestamp = int(now.timestamp() * 1000000)
ns_timestamp = int(now.timestamp() * 1000000000)
print(f'Seconds: {sec_timestamp}')
print(f'Milliseconds: {ms_timestamp}')
print(f'Microseconds: {us_timestamp}')
print(f'Nanoseconds: {ns_timestamp}')
import java.time.Instant;
// Java supports multiple precisions
Instant now = Instant.now();
long secTimestamp = now.getEpochSecond(); // 1735689600
long msTimestamp = now.toEpochMilli(); // 17356896000000
int nsTimestamp = now.getNano(); // Nanoseconds within second
System.out.println("Seconds: " + secTimestamp);
System.out.println("Milliseconds: " + msTimestamp);
System.out.println("Nanoseconds: " + nsTimestamp);
ISO 8601 Format
Definition
ISO 8601 is an international standard for representing dates and times. It's the most widely used format for storing and exchanging timestamps.
Format Variants
Basic ISO 8601 Formats:
1. Calendar Date: 2026-01-01
2. Date and Time: 2026-01-01T12:00:00
3. With Time Zone: 2026-01-01T12:00:00+08:00
4. UTC (Z notation): 2026-01-01T12:00:00Z
5. With Fractional Seconds: 2026-01-01T12:00:00.123Z
6. With Milliseconds: 2026-01-01T12:00:00.123Z
7. With Nanoseconds: 2026-01-01T12:00:00.123456789Z
Breaking Down ISO 8601
Format: YYYY-MM-DDThh:mm:ss.sssTZD
Components:
YYYY - Four-digit year (2026)
MM - Two-digit month (01)
DD - Two-digit day (01)
T - Separator between date and time
hh - Two-digit hour (00-23)
mm - Two-digit minute (00-59)
ss - Two-digit second (00-59)
sss - Fractional seconds (optional)
TZD - Time zone designator (Z, +08:00, -05:00)
Code Examples: ISO 8601
// JavaScript has built-in ISO 8601 support
const now = new Date();
const isoString = now.toISOString(); // "2026-01-01T12:00:00.000Z"
// Parse ISO 8601
const date = new Date('2026-01-01T12:00:00Z');
console.log('ISO 8601:', isoString);
console.log('Parsed:', date.toISOString());
from datetime import datetime, timezone
# Generate ISO 8601
now_utc = datetime.now(timezone.utc)
iso_string = now_utc.isoformat() # "2026-01-01T12:00:00+00:00"
# Parse ISO 8601
parsed_date = datetime.fromisoformat('2026-01-01T12:00:00+00:00')
print(f'ISO 8601: {iso_string}')
print(f'Parsed: {parsed_date.isoformat()}')
import java.time.Instant;
import java.time.format.DateTimeFormatter;
// Generate ISO 8601
Instant now = Instant.now();
String isoString = now.toString(); // "2026-01-01T12:00:00:00Z"
// Parse ISO 8601
Instant parsed = Instant.parse("2026-01-01T12:00:00:00Z");
System.out.println("ISO 8601: " + isoString);
System.out.println("Parsed: " + parsed);
RFC 3339 Format
Definition
RFC 3339 is a subset of ISO 8601 specifically designed for internet protocols and email standards.
Differences from ISO 8601
| Feature | ISO 8601 | RFC 3339 |
|---|---|---|
| Format | Multiple variants | Fixed format |
| Time Zone | Can use offset or Z | Can use offset or Z |
| Applications | General purpose | Internet protocols (HTTP, Email) |
| Fractional Seconds | Optional | Optional |
| Example | 2026-01-01T12:00:00+08:00 | 2026-01-01T12:00:00+08:00 |
Note: RFC 3339 is almost identical to ISO 8601. In practice, they're used interchangeably for internet applications.
Code Examples: RFC 3339
// RFC 3339 is similar to ISO 8601
const now = new Date();
const rfc3339String = now.toISOString(); // "2026-01-01T12:00:00.000Z"
// RFC 3339 commonly used in HTTP headers
const httpDate = now.toUTCString(); // "Wed, 01 Jan 2026 12:00:00 GMT"
console.log('RFC 3339:', rfc3339String);
console.log('HTTP Date:', httpDate);
from datetime import datetime, timezone
import email.utils
# Generate RFC 3339 (same as ISO 8601)
now_utc = datetime.now(timezone.utc)
rfc3339_string = now_utc.isoformat() # "2026-01-01T12:00:00+00:00"
# Generate HTTP date format
http_date = email.utils.format_datetime(now_utc)
print(f'RFC 3339: {rfc3339_string}')
print(f'HTTP Date: {http_date}')
Format Conversion
Unix Timestamp ↔ ISO 8601
// Unix to ISO 8601
function unixToIso(unixTimestamp, precision = 'ms') {
let ts = unixTimestamp;
if (precision === 's') {
ts = unixTimestamp * 1000;
} else if (precision === 'us') {
ts = unixTimestamp / 1000;
} else if (precision === 'ns') {
ts = unixTimestamp / 1000;
} else if (precision === 'ns') {
ts = unixTimestamp / 1000000;
}
return new Date(ts).toISOString();
}
// ISO 8601 to Unix
function isoToUnix(isoString) {
return Math.floor(new Date(isoString).getTime() / 1000);
}
// Examples
const unixTs = 1735689600;
const isoStr = unixToIso(unixTs); // "2026-01-01T00:00:00.000Z"
const backToUnix = isoToUnix(isoStr); // 1735689600
console.log('Unix → ISO:', isoStr);
console.log('ISO → Unix:', backToUnix);
from datetime import datetime, timezone
def unix_to_iso(unix_timestamp, precision='s'):
"""Convert Unix timestamp to ISO 8601 string"""
ts = unix_timestamp
if precision == 's':
ts = unix_timestamp
elif precision == 'ms':
ts = unix_timestamp / 1000
elif precision == 'us':
ts = unix_timestamp / 1000
elif precision == 'ns':
ts = unix_timestamp / 1000000
elif precision == 'ns':
ts = unix_timestamp / 1000000000
dt = datetime.fromtimestamp(ts, timezone.utc)
return dt.isoformat()
def iso_to_unix(iso_string):
"""Convert ISO 8601 string to Unix timestamp"""
dt = datetime.fromisoformat(iso_string)
return int(dt.timestamp())
# Examples
unix_ts = 1735689600
iso_str = unix_to_iso(unix_ts) # "2026-01-01T00:00:00+00:00"
back_to_unix = iso_to_unix(iso_str) # 1735689600
print(f'Unix → ISO: {iso_str}')
print(f'ISO → Unix: {back_to_unix}')
Precision Detection
Detecting Unix Timestamp Precision
function detectPrecision(timestamp) {
const str = timestamp.toString();
if (str.length === 10) {
return 'seconds';
} else if (str.length === 13) {
return 'milliseconds';
} else if (str.length === 16) {
return 'microseconds';
} else if (str.length === 19) {
return 'nanoseconds';
}
return 'unknown';
}
// Examples
console.log(detectPrecision(1735689600)); // "seconds"
console.log(detectPrecision(17356896000000)); // "milliseconds"
console.log(detectPrecision(173568960000000000)); // "microseconds"
console.log(detectPrecision(173568960000000000000)); // "nanoseconds"
def detect_precision(timestamp):
"""Detect Unix timestamp precision"""
str_ts = str(int(timestamp))
if len(str_ts) == 10:
return 'seconds'
elif len(str_ts) == 13:
return 'milliseconds'
elif len(str_ts) == 16:
return 'microseconds'
elif len(str_ts) == 19:
return 'nanoseconds'
return 'unknown'
# Examples
print(detect_precision(1735689600)) # "seconds"
print(detect_precision(173568960000000)) # "milliseconds"
print(detect_precision(173568960000000000)) # "microseconds"
print(detect_precision(173568960000000000000)) # "nanoseconds"
Comparison Table
Unix Timestamp vs ISO 8601 vs RFC 3339
| Aspect | Unix Timestamp | ISO 8601 | RFC 3339 |
|---|---|---|---|
| Format | Number (integer/float) | String | String |
| Human Readable | No | Yes | Yes |
| Time Zone Info | No (implicit UTC) | Yes (optional) | Yes (optional) |
| Precision | Configurable | Configurable | Configurable |
| Storage Size | 4-8 bytes | 20-30 bytes | 20-30 bytes |
| Database Support | Universal | Universal | Universal |
| Common Use | System timestamps | APIs, JSON, databases | HTTP, Email, APIs |
| Example | 1735689600 | 2026-01-01T12:00:00:00Z | 2026-01-01T12:00:00:00Z |
Recommendation: Use Unix timestamps for internal storage and calculations. Use ISO 8601/RFC 3339 for APIs, data exchange, and human-readable formats.
Best Practices
Storage
- Use Unix timestamps in databases for efficient storage and indexing
- Use ISO 8601 for external APIs and data exchange
- Always include time zones when displaying to users
- Document format in database schema comments
-- Best practice: Store Unix timestamp in database
CREATE TABLE events (
id INT PRIMARY KEY,
event_timestamp BIGINT, -- Unix timestamp in milliseconds
description TEXT,
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW()
);
API Responses
- Use ISO 8601 for API response bodies
- Include Unix timestamp for programmatic access
- Specify time zone clearly in responses
{
"event": {
"id": 123,
"timestamp": 173568960000000,
"iso8601": "2026-01-01T12:00:00:00Z",
"timezone": "UTC",
"human_readable": "January 1, 2026 at 12:00:00 AM UTC"
}
}
Error Handling
- Validate format before parsing
- Handle leap seconds in high-precision applications
- Graceful degradation for unknown formats
// Validate ISO 8601 format
function isValidISO8601(str) {
const isoRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2}:\d{2})?$/;
return isoRegex.test(str);
}
// Handle parsing errors
function safeParseISO8601(str) {
try {
return new Date(str);
} catch (error) {
console.error('Invalid ISO 8601 format:', str);
return new Date(); // Fallback to current time
}
}
Common Pitfalls
Pitfall 1: Assuming Unix Timestamp is Always Seconds
// ❌ Wrong: Always dividing by 1000
const timestamp = Date.now();
const wrongDate = new Date(timestamp / 1000); // Incorrect division
// ✅ Right: Check precision first
const date = new Date(timestamp); // Date accepts milliseconds directly
Pitfall 2: Ignoring Time Zones
// ❌ Wrong: Creating local time without timezone
const localTime = new Date('2026-01-01T12:00:00'); // Ambiguous
// ✅ Right: Specify timezone explicitly
const utcTime = new Date('2026-01-01T12:00:00Z'); // Clear UTC
const tokyoTime = new Date('2026-01-01T12:00:00+09:00'); // Tokyo time
Pitfall 3: Mixing Formats
// ❌ Wrong: Inconsistent formats in API
{
"timestamp": 1735689600,
"date": "01/01/2026",
"time": "12:00 PM",
"datetime": "2026-01-01 12:00"
}
// ✅ Right: Consistent ISO 8601 format
{
"timestamp": 1735689600,
"iso8601": "2026-01-01T12:00:00:00Z",
"timezone": "UTC"
}
Related Tools
- Unix Timestamp Converter - Convert between Unix timestamps and dates with auto precision detection
- ISO 8601 Converter - Convert to/from ISO 8601 format
- RFC 3339 Converter - Work with RFC 3339 timestamp format
- Current Timestamp - Get current time in multiple formats and precisions
- Timestamp Validator - Validate and detect timestamp formats
FAQ
Q: What's the difference between ISO 8601 and RFC 3339?
A: RFC 3339 is a subset of ISO 8601 designed for internet protocols. They're nearly identical in practice, but RFC 3339 has stricter format rules.
Q: How do I know if a Unix timestamp is in seconds or milliseconds?
A: Count digits: 10 digits = seconds, 13 digits = milliseconds. You can also check the year (seconds = 1970+, milliseconds = 1970+).
Q: What precision should I use for my application?
A: Use milliseconds for general web applications (JavaScript default), seconds for database storage efficiency, or microseconds/nanoseconds for high-precision timing.
Q: Does ISO 8601 support time zones?
A: Yes, ISO 8601 supports time zone offsets (+08:00) and Z notation for UTC.
Q: How do I handle time zones with Unix timestamps?
A: Unix timestamps are always UTC. Convert to local time only when displaying to users using their timezone settings.
Q: What's the maximum Unix timestamp value?
A: For 64-bit systems: January 19, 2038 (year 2038 problem) is not an issue. The theoretical maximum is billions of years into the future.