DateTimeFromUnixNs
Description
Break a UTC nanoseconds-since-epoch value down into a DateTime, rendered at the fixed offset utc_offset_seconds (east-positive). Pass 0 to render in UTC.
Parameters
| Name | Direction | Description |
|---|---|---|
unix_ns |
in | Nanoseconds since the Unix epoch (UTC). |
utc_offset_seconds |
in | Offset to apply before breaking down; recorded verbatim in the result’s utc_offset_seconds. |
Success
Returns the corresponding DateTime.
Failure
Cannot fail.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Io.c:1749:
// Derive the weekday from the canonical conversion so a parsed value
// carries a correct weekday regardless of the input text.
tmp.weekday = DateTimeFromUnixNs(DateTimeToUnixNs(tmp), offset).weekday;
*dt = tmp;
return p;- In
DateTime.c:39:
}
DateTime DateTimeFromUnixNs(u64 unix_ns, i32 utc_offset_seconds) {
i64 total_sec = (i64)(unix_ns / (u64)NS_PER_SEC);
u32 nanos = (u32)(unix_ns % (u64)NS_PER_SEC);- In
DateTime.c:96:
DateTime DateTimeAddNs(DateTime dt, i64 delta_ns) {
u64 base = DateTimeToUnixNs(dt);
return DateTimeFromUnixNs((u64)((i64)base + delta_ns), dt.utc_offset_seconds);
}- In
Clock.c:105:
DateTime ClockUtc(void) {
return DateTimeFromUnixNs(ClockRealNs(), 0);
}- In
Clock.c:116:
DefaultAllocatorDeinit(&alloc);
if (ok)
return DateTimeFromUnixNs(ns, offset);
#endif
return DateTimeFromUnixNs(ns, 0);- In
Clock.c:118:
return DateTimeFromUnixNs(ns, offset);
#endif
return DateTimeFromUnixNs(ns, 0);
}- In
Io.Write.c:913:
u64 base = 1609459200ull * 1000000000ull; // 2021-01-01T00:00:00Z
DateTime utc = DateTimeFromUnixNs(base, 0);
StrClear(&s);
StrAppendFmt(&s, "{}", utc);- In
Io.Write.c:918:
ok = ok && ZstrCompare(StrBegin(&s), "2021-01-01T00:00:00Z") == 0;
DateTime ist = DateTimeFromUnixNs(base, 19800); // +05:30
StrClear(&s);
StrAppendFmt(&s, "{}", ist);- In
Io.Write.c:923:
ok = ok && ZstrCompare(StrBegin(&s), "2021-01-01T05:30:00+05:30") == 0;
DateTime neg = DateTimeFromUnixNs(base, -34200); // -09:30
StrClear(&s);
StrAppendFmt(&s, "{}", neg);- In
Io.Write.c:928:
ok = ok && ZstrCompare(StrBegin(&s), "2020-12-31T14:30:00-09:30") == 0;
DateTime frac = DateTimeFromUnixNs(base + 123456789ull, 0);
StrClear(&s);
StrAppendFmt(&s, "{}", frac);- In
DateTime.c:19:
for (u32 s = 0; s < sizeof(samples) / sizeof(samples[0]); ++s) {
for (u32 o = 0; o < sizeof(offsets) / sizeof(offsets[0]); ++o) {
DateTime d = DateTimeFromUnixNs(samples[s], offsets[o]);
if (DateTimeToUnixNs(d) != samples[s]) {
return false;- In
DateTime.c:35:
static bool test_compare(void) {
DateTime a = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0);
DateTime b = DateTimeFromUnixNs((T_2021 + 1) * NS_PER_SEC, 0);
// Same instant rendered in two zones compares equal.
- In
DateTime.c:36:
static bool test_compare(void) {
DateTime a = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0);
DateTime b = DateTimeFromUnixNs((T_2021 + 1) * NS_PER_SEC, 0);
// Same instant rendered in two zones compares equal.
DateTime c = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, IST);- In
DateTime.c:38:
DateTime b = DateTimeFromUnixNs((T_2021 + 1) * NS_PER_SEC, 0);
// Same instant rendered in two zones compares equal.
DateTime c = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, IST);
return DateTimeCompare(a, b) == -1 && DateTimeCompare(b, a) == 1 && DateTimeCompare(a, c) == 0;
}- In
DateTime.c:43:
static bool test_diff(void) {
DateTime a = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0);
DateTime b = DateTimeFromUnixNs((T_2021 + 90) * NS_PER_SEC, 0);
return DateTimeDiffNs(b, a) == 90ll * (i64)NS_PER_SEC && DateTimeDiffNs(a, b) == -90ll * (i64)NS_PER_SEC;- In
DateTime.c:44:
static bool test_diff(void) {
DateTime a = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0);
DateTime b = DateTimeFromUnixNs((T_2021 + 90) * NS_PER_SEC, 0);
return DateTimeDiffNs(b, a) == 90ll * (i64)NS_PER_SEC && DateTimeDiffNs(a, b) == -90ll * (i64)NS_PER_SEC;
}- In
DateTime.c:49:
static bool test_add(void) {
DateTime a = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, IST);
DateTime b = DateTimeAddNs(a, 86400ll * (i64)NS_PER_SEC); // +1 day
return b.day == 2 && b.month == 1 && b.year == 2021 && b.utc_offset_seconds == IST &&- In
DateTime.c:84:
for (u32 m = 1; m <= 12; ++m) {
DateTime d = {.year = years[yi], .month = (u8)m, .day = 15, .hour = 13, .minute = 7, .second = 5};
DateTime r = DateTimeFromUnixNs(DateTimeToUnixNs(d), 0);
if (r.year != years[yi] || r.month != (u8)m || r.day != 15 || r.hour != 13 || r.minute != 7 ||
r.second != 5) {- In
DateTime.c:96:
static bool test_leap_day_roundtrip(void) {
DateTime feb29 = {.year = 2024, .month = 2, .day = 29, .hour = 23, .minute = 59, .second = 59};
DateTime r = DateTimeFromUnixNs(DateTimeToUnixNs(feb29), 0);
return r.year == 2024 && r.month == 2 && r.day == 29 && r.hour == 23 && r.minute == 59 && r.second == 59;
}- In
DateTime.c:103:
// 1970-01-01 Thu(4), 2021-01-01 Fri(5), 2000-01-01 Sat(6), 2024-02-29
// Thu(4), 2023-01-01 Sun(0) (the wd==0 case pins the `wd < 0` guard).
return DateTimeFromUnixNs(0, 0).weekday == 4 && DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0).weekday == 5 &&
DateTimeFromUnixNs(946684800ull * NS_PER_SEC, 0).weekday == 6 &&
DateTimeFromUnixNs(1709164800ull * NS_PER_SEC, 0).weekday == 4 &&- In
DateTime.c:104:
// Thu(4), 2023-01-01 Sun(0) (the wd==0 case pins the `wd < 0` guard).
return DateTimeFromUnixNs(0, 0).weekday == 4 && DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0).weekday == 5 &&
DateTimeFromUnixNs(946684800ull * NS_PER_SEC, 0).weekday == 6 &&
DateTimeFromUnixNs(1709164800ull * NS_PER_SEC, 0).weekday == 4 &&
DateTimeFromUnixNs(1672531200ull * NS_PER_SEC, 0).weekday == 0;- In
DateTime.c:105:
return DateTimeFromUnixNs(0, 0).weekday == 4 && DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0).weekday == 5 &&
DateTimeFromUnixNs(946684800ull * NS_PER_SEC, 0).weekday == 6 &&
DateTimeFromUnixNs(1709164800ull * NS_PER_SEC, 0).weekday == 4 &&
DateTimeFromUnixNs(1672531200ull * NS_PER_SEC, 0).weekday == 0;
}- In
DateTime.c:106:
DateTimeFromUnixNs(946684800ull * NS_PER_SEC, 0).weekday == 6 &&
DateTimeFromUnixNs(1709164800ull * NS_PER_SEC, 0).weekday == 4 &&
DateTimeFromUnixNs(1672531200ull * NS_PER_SEC, 0).weekday == 0;
}- In
DateTime.c:117:
DateTime jan1 = {.year = y, .month = 1, .day = 1};
DateTime dec31 = {.year = y, .month = 12, .day = 31};
DateTime rj = DateTimeFromUnixNs(DateTimeToUnixNs(jan1), 0);
DateTime rd = DateTimeFromUnixNs(DateTimeToUnixNs(dec31), 0);
if (rj.year != y || rj.month != 1 || rj.day != 1) {- In
DateTime.c:118:
DateTime dec31 = {.year = y, .month = 12, .day = 31};
DateTime rj = DateTimeFromUnixNs(DateTimeToUnixNs(jan1), 0);
DateTime rd = DateTimeFromUnixNs(DateTimeToUnixNs(dec31), 0);
if (rj.year != y || rj.month != 1 || rj.day != 1) {
return false;- In
DateTime.c:135:
};
for (u32 i = 0; i < sizeof(exact) / sizeof(exact[0]); ++i) {
DateTime r = DateTimeFromUnixNs(DateTimeToUnixNs(exact[i]), 0);
if (r.year != exact[i].year || r.month != exact[i].month || r.day != exact[i].day) {
return false;- In
DateTime.c:147:
DefaultAllocator alloc = DefaultAllocatorInit();
Str s = StrInit(&alloc);
DateTime d = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0);
StrAppendFmt(&s, "{}", d);
bool ok = ZstrCompare(StrBegin(&s), "2021-01-01T00:00:00Z") == 0;- In
DateTime.c:158:
DefaultAllocator alloc = DefaultAllocatorInit();
Str s = StrInit(&alloc);
DateTime d = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, IST);
StrAppendFmt(&s, "{}", d);
bool ok = ZstrCompare(StrBegin(&s), "2021-01-01T05:30:00+05:30") == 0;- In
DateTime.c:169:
DefaultAllocator alloc = DefaultAllocatorInit();
Str s = StrInit(&alloc);
DateTime d = DateTimeFromUnixNs(T_2021 * NS_PER_SEC + 123456789ull, 0);
StrAppendFmt(&s, "{}", d);
bool ok = ZstrCompare(StrBegin(&s), "2021-01-01T00:00:00.123456789Z") == 0;- In
DateTime.c:181:
DefaultAllocator alloc = DefaultAllocatorInit();
Str s = StrInit(&alloc);
DateTime a = DateTimeFromUnixNs(T_2021 * NS_PER_SEC + 123456789ull, MST);
StrAppendFmt(&s, "{}", a);- In
Clock.c:26:
static bool test_epoch_zero(void) {
DateTime d = DateTimeFromUnixNs(0, 0);
return d.year == 1970 && d.month == 1 && d.day == 1 && d.hour == 0 && d.minute == 0 && d.second == 0 &&
d.weekday == 4 /* Thursday */ && d.nanosecond == 0 && d.utc_offset_seconds == 0;- In
Clock.c:32:
static bool test_known_utc_instant(void) {
DateTime d = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, 0);
return d.year == 2021 && d.month == 1 && d.day == 1 && d.hour == 0 && d.minute == 0 && d.second == 0 &&
d.weekday == 5 /* Friday */;- In
Clock.c:38:
static bool test_offset_shifts_wall_fields(void) {
DateTime d = DateTimeFromUnixNs(T_2021 * NS_PER_SEC, IST_OFFSET);
return d.year == 2021 && d.month == 1 && d.day == 1 && d.hour == 5 && d.minute == 30 && d.second == 0 &&
d.weekday == 5 && d.utc_offset_seconds == IST_OFFSET;- In
Clock.c:44:
static bool test_subsecond_preserved(void) {
DateTime d = DateTimeFromUnixNs(T_2021 * NS_PER_SEC + 123456789ull, 0);
return d.second == 0 && d.nanosecond == 123456789;
}
Last updated on