指南

理解时间戳格式

本文暂提供英文版,中文翻译正在完善中。

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

PrecisionExampleMagnitudeCommon Use
Seconds173568960010 digitsUnix/Linux systems
Milliseconds1735689600000013 digitsJavaScript, Web APIs
Microseconds17356896000000000016 digitsHigh-precision timing
Nanoseconds17356896000000000000019 digitsScientific 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

FeatureISO 8601RFC 3339
FormatMultiple variantsFixed format
Time ZoneCan use offset or ZCan use offset or Z
ApplicationsGeneral purposeInternet protocols (HTTP, Email)
Fractional SecondsOptionalOptional
Example2026-01-01T12:00:00+08:002026-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

AspectUnix TimestampISO 8601RFC 3339
FormatNumber (integer/float)StringString
Human ReadableNoYesYes
Time Zone InfoNo (implicit UTC)Yes (optional)Yes (optional)
PrecisionConfigurableConfigurableConfigurable
Storage Size4-8 bytes20-30 bytes20-30 bytes
Database SupportUniversalUniversalUniversal
Common UseSystem timestampsAPIs, JSON, databasesHTTP, Email, APIs
Example17356896002026-01-01T12:00:00:00Z2026-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

  1. Use Unix timestamps in databases for efficient storage and indexing
  2. Use ISO 8601 for external APIs and data exchange
  3. Always include time zones when displaying to users
  4. 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

  1. Use ISO 8601 for API response bodies
  2. Include Unix timestamp for programmatic access
  3. 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

  1. Validate format before parsing
  2. Handle leap seconds in high-precision applications
  3. 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

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.