nx_timefmt.nx
buildroot/runtime/nx_timefmt.nx
about
timefmt.nx -- RFC 3339 + RFC 822 timestamp format/parse.
Used by:
- TLS 1.3 / X.509 cert validity (notBefore / notAfter).
X.509 uses UTCTime (YYMMDDhhmmssZ) for dates before 2050
and GeneralizedTime (YYYYMMDDhhmmssZ) after. We support
both formats for parse.
- HTTP Date header (RFC 7231 ยง7.1.1.1) -- RFC 822 format.
- Structured logs in Nishi services.
- JSON responses (RFC 3339 via ISO 8601 subset).
NO time zone handling today. All conversion is against UTC only;
local time zones require a tz database we haven't built. TLS
cert dates are always UTC, HTTP Date must be UTC-in-practice
("GMT"), so this covers the load-bearing cases.
Format reference (RFC 3339):
date-time = full-date "T" full-time
full-date = date-fullyear "-" date-month "-" date-mday
full-time = partial-time time-offset
partial-time = hour ":" minute ":" second [ "." secfrac ]
time-offset = "Z" / ( ("+" / "-") hour ":" minute )
We emit the "Z" form exclusively: "YYYY-MM-DDTHH:MM:SSZ" (20 chars).
Invariants:
T1 format_rfc3339 writes exactly 20 ASCII bytes plus NUL-free
(caller adds terminator if needed)
T2 Dates before year 1 are out of scope; years > 9999 are
clamped to 9999 so the output stays 20 chars
T3 No Y2K / 2038-bugginess. i64 epoch seconds handle every
human-relevant date from ~292 BC to ~292 billion AD.
license_tier: INDEPENDENT_REDERIVE
genealogy_id: international-research-sources/ietf/rfc_8446
dependencies 1 imports · 3 importers
imports: nx_syscalls.nx
imported by: nx_log_v1.nxnx_timefmt_gate.nxnx_x509_validity.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 45 | const K_MAGIC_146097: i64 = 146097 |
| 46 | const K_MAGIC_719468: i64 = 719468 |
| 47 | const K_MAGIC_1460: i64 = 1460 |
| 48 | const K_MAGIC_36524: i64 = 36524 |
| 49 | const K_MAGIC_146096: i64 = 146096 |
| 50 | const K_MAGIC_86400: i64 = 86400 |
| 51 | const K_MAGIC_3600: i64 = 3600 |
| 52 | const K_MAGIC_9999: i64 = 9999 |
| 53 | const K_MAGIC_1900: i64 = 1900 |
| 54 | const K_MAGIC_2000: i64 = 2000 |
| 55 | const K_MAGIC_1970: i64 = 1970 |
| 56 | const K_MAGIC_1234567890: i64 = 1234567890 |
functions
| 65 | func is_leap(y: i64) -> i64 called by 1: main |
| 74 | func days_from_civil(y: i64, m: i64, d: i64) -> i64 |
| 87 | func civil_from_days(days: i64, y_out: *i64, m_out: *i64, d_out: *i64) -> i64 |
| 110 | func break_down_utc(epoch_secs: i64, |
| 134 | func emit_zpad(out: *u8, pos: i64, n: i64, width: i64) -> i64 called by 1: format_rfc3339 |
| 147 | func format_rfc3339(epoch_secs: i64, out: *u8) -> i64 |
| 190 | func parse_2digit(buf: *u8, off: i64) -> i64 |
| 200 | func parse_4digit(buf: *u8, off: i64) -> i64 |
| 210 | func parse_utctime(buf: *u8) -> i64 |
| 230 | func parse_gentime(buf: *u8) -> i64 |
| 247 | func main() -> i64 |