RFC 3339: Format Tanggal/Waktu Internet

What Is RFC 3339?

RFC 3339 ("Date and Time on the Internet: Timestamps") is an IETF standard that defines a profile of ISO 8601 specifically designed for use in internet protocols. Published in 2002, it is the format used in HTTP headers, RSS/Atom feeds, JWT tokens, OpenAPI specifications, and most modern web APIs. The key requirement is that all datetimes must include a timezone offset.

RFC 3339 Format

2024-03-01T14:30:00Z          # UTC (Z suffix required, not optional)
2024-03-01T14:30:00+09:00     # With positive offset
2024-03-01T14:30:00-05:00     # With negative offset
2024-03-01T14:30:00.456Z      # With sub-second precision
2024-03-01t14:30:00z          # Lowercase T and Z also valid per spec

RFC 3339 vs ISO 8601: Key Differences

  • Timezone required: RFC 3339 always requires a timezone offset. ISO 8601 allows "local time" with no offset.
  • No week dates: RFC 3339 does not allow ISO 8601's week format (2024-W09-5).
  • No ordinal dates: 2024-061 (day 61 of year) is valid ISO 8601 but not RFC 3339.
  • Separator: RFC 3339 requires T between date and time (ISO 8601 allows a space).
  • Strict subset: All valid RFC 3339 timestamps are valid ISO 8601, but not vice versa.

Where RFC 3339 Is Used

  • HTTP: Last-Modified, Date headers (though HTTP/1.1 uses RFC 7231 / IMF-fixdate)
  • Atom feeds: <updated>2024-03-01T14:30:00Z</updated>
  • JWT (JSON Web Tokens): iat, exp, nbf claims use Unix timestamps, but RFC 3339 is used in related specs
  • OpenAPI 3.0: format: date-time is defined as RFC 3339
  • Go's time package: time.RFC3339 = "2006-01-02T15:04:05Z07:00"
  • Rust's chrono crate: default serialization format

Parsing RFC 3339 in Code

# Python 3.11+ — datetime.fromisoformat handles RFC 3339
from datetime import datetime
dt = datetime.fromisoformat("2024-03-01T14:30:00+09:00")

# Python 3.10 and below — use dateutil
from dateutil.parser import parse
dt = parse("2024-03-01T14:30:00+09:00")

# JavaScript
new Date("2024-03-01T14:30:00Z")  // native support

# Go
t, err := time.Parse(time.RFC3339, "2024-03-01T14:30:00Z")

# Rust
use chrono::DateTime;
let dt = DateTime::parse_from_rfc3339("2024-03-01T14:30:00Z").unwrap();

Recommendation

Use RFC 3339 format for all datetime values in APIs, configuration files, and logs. It is the most widely supported internet datetime format, and its strict timezone requirement prevents the ambiguity that causes bugs.