diff --git a/lib/std/event/batch.zig b/lib/std/event/batch.zig index 9c424fcd2c..8f2954d85b 100644 --- a/lib/std/event/batch.zig +++ b/lib/std/event/batch.zig @@ -122,7 +122,7 @@ test "std.event.Batch" { } fn sleepALittle(count: *usize) void { - std.time.sleep(1 * std.time.millisecond); + std.time.sleep(1 * std.time.ns_per_ms); _ = @atomicRmw(usize, count, .Add, 1, .SeqCst); } diff --git a/lib/std/event/group.zig b/lib/std/event/group.zig index 155a9486b7..61130b32cb 100644 --- a/lib/std/event/group.zig +++ b/lib/std/event/group.zig @@ -145,7 +145,7 @@ fn testGroup(allocator: *Allocator) callconv(.Async) void { testing.expectError(error.ItBroke, another.wait()); } fn sleepALittle(count: *usize) callconv(.Async) void { - std.time.sleep(1 * std.time.millisecond); + std.time.sleep(1 * std.time.ns_per_ms); _ = @atomicRmw(usize, count, .Add, 1, .SeqCst); } fn increaseByTen(count: *usize) callconv(.Async) void { diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index 607e2f24ca..0abcad32e1 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -457,7 +457,7 @@ pub const Loop = struct { => { // Even poll() didn't work. The best we can do now is sleep for a // small duration and then hope that something changed. - std.time.sleep(1 * std.time.millisecond); + std.time.sleep(1 * std.time.ns_per_ms); }, }; resume @frame(); diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index f8cf69cbb8..a9ee996e4b 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -227,14 +227,12 @@ pub const File = struct { size: u64, mode: Mode, - /// access time in nanoseconds - atime: i64, - - /// last modification time in nanoseconds - mtime: i64, - - /// creation time in nanoseconds - ctime: i64, + /// Access time in nanoseconds, relative to UTC 1970-01-01. + atime: i128, + /// Last modification time in nanoseconds, relative to UTC 1970-01-01. + mtime: i128, + /// Creation time in nanoseconds, relative to UTC 1970-01-01. + ctime: i128, }; pub const StatError = os.FStatError; @@ -270,9 +268,9 @@ pub const File = struct { .inode = st.ino, .size = @bitCast(u64, st.size), .mode = st.mode, - .atime = @as(i64, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec, - .mtime = @as(i64, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec, - .ctime = @as(i64, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec, + .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec, + .mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec, + .ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec, }; } @@ -286,9 +284,9 @@ pub const File = struct { pub fn updateTimes( self: File, /// access timestamp in nanoseconds - atime: i64, + atime: i128, /// last modification timestamp in nanoseconds - mtime: i64, + mtime: i128, ) UpdateTimesError!void { if (builtin.os.tag == .windows) { const atime_ft = windows.nanoSecondsToFileTime(atime); diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index a857c3a7f8..2d979f5690 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -10,7 +10,7 @@ test "openSelfExe" { self_exe_file.close(); } -const FILE_LOCK_TEST_SLEEP_TIME = 5 * std.time.millisecond; +const FILE_LOCK_TEST_SLEEP_TIME = 5 * std.time.ns_per_ms; test "open file with exclusive nonblocking lock twice" { if (builtin.os.tag == .wasi) return error.SkipZigTest; @@ -142,8 +142,8 @@ const FileLockTestContext = struct { // Output variables err: ?(File.OpenError || std.os.ReadError) = null, - start_time: u64 = 0, - end_time: u64 = 0, + start_time: i64 = 0, + end_time: i64 = 0, bytes_read: ?usize = null, fn overlaps(self: *const @This(), other: *const @This()) bool { diff --git a/lib/std/net.zig b/lib/std/net.zig index 96c95fc497..067c9026b0 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -1135,13 +1135,13 @@ fn resMSendRc( }}; const retry_interval = timeout / attempts; var next: u32 = 0; - var t2: u64 = std.time.milliTimestamp(); + var t2: u64 = @bitCast(u64, std.time.milliTimestamp()); var t0 = t2; var t1 = t2 - retry_interval; var servfail_retry: usize = undefined; - outer: while (t2 - t0 < timeout) : (t2 = std.time.milliTimestamp()) { + outer: while (t2 - t0 < timeout) : (t2 = @bitCast(u64, std.time.milliTimestamp())) { if (t2 - t1 >= retry_interval) { // Query all configured nameservers in parallel var i: usize = 0; diff --git a/lib/std/os.zig b/lib/std/os.zig index bc8803e3b0..22c884fce8 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -3880,6 +3880,8 @@ pub fn dl_iterate_phdr( pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError; +/// TODO: change this to return the timespec as a return value +/// TODO: look into making clk_id an enum pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { if (std.Target.current.os.tag == .wasi) { var ts: timestamp_t = undefined; @@ -3895,6 +3897,23 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { } return; } + if (std.Target.current.os.tag == .windows) { + if (clk_id == CLOCK_REALTIME) { + var ft: windows.FILETIME = undefined; + windows.kernel32.GetSystemTimeAsFileTime(&ft); + // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch. + const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + const ft_per_s = std.time.ns_per_s / 100; + tp.* = .{ + .tv_sec = @intCast(i64, ft64 / ft_per_s) + std.time.epoch.windows, + .tv_nsec = @intCast(c_long, ft64 % ft_per_s) * 100, + }; + return; + } else { + // TODO POSIX implementation of CLOCK_MONOTONIC on Windows. + return error.UnsupportedClock; + } + } switch (errno(system.clock_gettime(clk_id, tp))) { 0 => return, diff --git a/lib/std/os/bits/darwin.zig b/lib/std/os/bits/darwin.zig index 24f20b70ea..4581490e6f 100644 --- a/lib/std/os/bits/darwin.zig +++ b/lib/std/os/bits/darwin.zig @@ -1456,3 +1456,12 @@ pub const POLLHUP = 0x010; pub const POLLNVAL = 0x020; pub const POLLSTANDARD = POLLIN | POLLPRI | POLLOUT | POLLRDNORM | POLLRDBAND | POLLWRBAND | POLLERR | POLLHUP | POLLNVAL; + +pub const CLOCK_REALTIME = 0; +pub const CLOCK_MONOTONIC = 6; +pub const CLOCK_MONOTONIC_RAW = 4; +pub const CLOCK_MONOTONIC_RAW_APPROX = 5; +pub const CLOCK_UPTIME_RAW = 8; +pub const CLOCK_UPTIME_RAW_APPROX = 9; +pub const CLOCK_PROCESS_CPUTIME_ID = 12; +pub const CLOCK_THREAD_CPUTIME_ID = 16; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index ff10c08865..e1d54743ab 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -1193,23 +1193,23 @@ pub fn peb() *PEB { /// Universal Time (UTC). /// This function returns the number of nanoseconds since the canonical epoch, /// which is the POSIX one (Jan 01, 1970 AD). -pub fn fromSysTime(hns: i64) i64 { - const adjusted_epoch = hns + std.time.epoch.windows * (std.time.ns_per_s / 100); +pub fn fromSysTime(hns: i64) i128 { + const adjusted_epoch = @as(i128, hns + std.time.epoch.windows) * (std.time.ns_per_s / 100); return adjusted_epoch * 100; } -pub fn toSysTime(ns: i64) i64 { +pub fn toSysTime(ns: i128) i64 { const hns = @divFloor(ns, 100); - return hns - std.time.epoch.windows * (std.time.ns_per_s / 100); + return @intCast(i64, hns) - std.time.epoch.windows * (std.time.ns_per_s / 100); } -pub fn fileTimeToNanoSeconds(ft: FILETIME) i64 { - const hns = @bitCast(i64, (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime); +pub fn fileTimeToNanoSeconds(ft: FILETIME) i128 { + const hns = (@as(i64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime; return fromSysTime(hns); } /// Converts a number of nanoseconds since the POSIX epoch to a Windows FILETIME. -pub fn nanoSecondsToFileTime(ns: i64) FILETIME { +pub fn nanoSecondsToFileTime(ns: i128) FILETIME { const adjusted = @bitCast(u64, toSysTime(ns)); return FILETIME{ .dwHighDateTime = @truncate(u32, adjusted >> 32), diff --git a/lib/std/progress.zig b/lib/std/progress.zig index d73f3ee139..d80f8c4423 100644 --- a/lib/std/progress.zig +++ b/lib/std/progress.zig @@ -31,10 +31,10 @@ pub const Progress = struct { output_buffer: [100]u8 = undefined, /// How many nanoseconds between writing updates to the terminal. - refresh_rate_ns: u64 = 50 * std.time.millisecond, + refresh_rate_ns: u64 = 50 * std.time.ns_per_ms, /// How many nanoseconds to keep the output hidden - initial_delay_ns: u64 = 500 * std.time.millisecond, + initial_delay_ns: u64 = 500 * std.time.ns_per_ms, done: bool = true, @@ -282,24 +282,24 @@ test "basic functionality" { next_sub_task = (next_sub_task + 1) % sub_task_names.len; node.completeOne(); - std.time.sleep(5 * std.time.millisecond); + std.time.sleep(5 * std.time.ns_per_ms); node.completeOne(); node.completeOne(); - std.time.sleep(5 * std.time.millisecond); + std.time.sleep(5 * std.time.ns_per_ms); node.completeOne(); node.completeOne(); - std.time.sleep(5 * std.time.millisecond); + std.time.sleep(5 * std.time.ns_per_ms); node.end(); - std.time.sleep(5 * std.time.millisecond); + std.time.sleep(5 * std.time.ns_per_ms); } { var node = root_node.start("this is a really long name designed to activate the truncation code. let's find out if it works", null); node.activate(); - std.time.sleep(10 * std.time.millisecond); + std.time.sleep(10 * std.time.ns_per_ms); progress.refresh(); - std.time.sleep(10 * std.time.millisecond); + std.time.sleep(10 * std.time.ns_per_ms); node.end(); } } diff --git a/lib/std/reset_event.zig b/lib/std/reset_event.zig index 860f494f3f..6f520773d8 100644 --- a/lib/std/reset_event.zig +++ b/lib/std/reset_event.zig @@ -152,15 +152,15 @@ const PosixEvent = struct { if (comptime std.Target.current.isDarwin()) { var tv: os.darwin.timeval = undefined; assert(os.darwin.gettimeofday(&tv, null) == 0); - timeout_abs += @intCast(u64, tv.tv_sec) * time.second; - timeout_abs += @intCast(u64, tv.tv_usec) * time.microsecond; + timeout_abs += @intCast(u64, tv.tv_sec) * time.ns_per_s; + timeout_abs += @intCast(u64, tv.tv_usec) * time.us_per_s; } else { os.clock_gettime(os.CLOCK_REALTIME, &ts) catch unreachable; - timeout_abs += @intCast(u64, ts.tv_sec) * time.second; + timeout_abs += @intCast(u64, ts.tv_sec) * time.ns_per_s; timeout_abs += @intCast(u64, ts.tv_nsec); } - ts.tv_sec = @intCast(@TypeOf(ts.tv_sec), @divFloor(timeout_abs, time.second)); - ts.tv_nsec = @intCast(@TypeOf(ts.tv_nsec), @mod(timeout_abs, time.second)); + ts.tv_sec = @intCast(@TypeOf(ts.tv_sec), @divFloor(timeout_abs, time.ns_per_s)); + ts.tv_nsec = @intCast(@TypeOf(ts.tv_nsec), @mod(timeout_abs, time.ns_per_s)); } while (!self.is_set) { diff --git a/lib/std/time.zig b/lib/std/time.zig index dd9a521543..8fb2b79fd2 100644 --- a/lib/std/time.zig +++ b/lib/std/time.zig @@ -4,16 +4,14 @@ const assert = std.debug.assert; const testing = std.testing; const os = std.os; const math = std.math; +const is_windows = std.Target.current.os.tag == .windows; pub const epoch = @import("time/epoch.zig"); -const is_windows = std.Target.current.os.tag == .windows; - /// Spurious wakeups are possible and no precision of timing is guaranteed. /// TODO integrate with evented I/O pub fn sleep(nanoseconds: u64) void { if (is_windows) { - const ns_per_ms = ns_per_s / ms_per_s; const big_ms_from_ns = nanoseconds / ns_per_ms; const ms = math.cast(os.windows.DWORD, big_ms_from_ns) catch math.maxInt(os.windows.DWORD); os.windows.kernel32.Sleep(ms); @@ -49,69 +47,78 @@ pub fn sleep(nanoseconds: u64) void { std.os.nanosleep(s, ns); } -/// Get the posix timestamp, UTC, in seconds -/// TODO audit this function. is it possible to return an error? -pub fn timestamp() u64 { - return @divFloor(milliTimestamp(), ms_per_s); +/// Get a calendar timestamp, in seconds, relative to UTC 1970-01-01. +/// Precision of timing depends on the hardware and operating system. +/// The return value is signed because it is possible to have a date that is +/// before the epoch. +/// See `std.os.clock_gettime` for a POSIX timestamp. +pub fn timestamp() i64 { + return @divFloor(milliTimestamp(), ns_per_s); } -/// Get the posix timestamp, UTC, in milliseconds -/// TODO audit this function. is it possible to return an error? -pub fn milliTimestamp() u64 { +/// Get a calendar timestamp, in milliseconds, relative to UTC 1970-01-01. +/// Precision of timing depends on the hardware and operating system. +/// The return value is signed because it is possible to have a date that is +/// before the epoch. +/// See `std.os.clock_gettime` for a POSIX timestamp. +pub fn milliTimestamp() i64 { + return @intCast(i64, @divFloor(nanoTimestamp(), ns_per_ms)); +} + +/// Get a calendar timestamp, in nanoseconds, relative to UTC 1970-01-01. +/// Precision of timing depends on the hardware and operating system. +/// On Windows this has a maximum granularity of 100 nanoseconds. +/// The return value is signed because it is possible to have a date that is +/// before the epoch. +/// See `std.os.clock_gettime` for a POSIX timestamp. +pub fn nanoTimestamp() i128 { if (is_windows) { - //FileTime has a granularity of 100 nanoseconds - // and uses the NTFS/Windows epoch + // FileTime has a granularity of 100 nanoseconds and uses the NTFS/Windows epoch, + // which is 1601-01-01. + const epoch_adj = epoch.windows * (ns_per_s / 100); var ft: os.windows.FILETIME = undefined; os.windows.kernel32.GetSystemTimeAsFileTime(&ft); - const hns_per_ms = (ns_per_s / 100) / ms_per_s; - const epoch_adj = epoch.windows * ms_per_s; - const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime; - return @divFloor(ft64, hns_per_ms) - -epoch_adj; + return @as(i128, @bitCast(i64, ft64) + epoch_adj) * 100; } if (builtin.os.tag == .wasi and !builtin.link_libc) { var ns: os.wasi.timestamp_t = undefined; - - // TODO: Verify that precision is ignored const err = os.wasi.clock_time_get(os.wasi.CLOCK_REALTIME, 1, &ns); assert(err == os.wasi.ESUCCESS); - - const ns_per_ms = 1000; - return @divFloor(ns, ns_per_ms); - } - if (comptime std.Target.current.isDarwin()) { - var tv: os.darwin.timeval = undefined; - var err = os.darwin.gettimeofday(&tv, null); - assert(err == 0); - const sec_ms = tv.tv_sec * ms_per_s; - const usec_ms = @divFloor(tv.tv_usec, us_per_s / ms_per_s); - return @intCast(u64, sec_ms + usec_ms); + return ns; } var ts: os.timespec = undefined; - //From what I can tell there's no reason clock_gettime - // should ever fail for us with CLOCK_REALTIME, - // seccomp aside. - os.clock_gettime(os.CLOCK_REALTIME, &ts) catch unreachable; - const sec_ms = @intCast(u64, ts.tv_sec) * ms_per_s; - const nsec_ms = @divFloor(@intCast(u64, ts.tv_nsec), ns_per_s / ms_per_s); - return sec_ms + nsec_ms; + os.clock_gettime(os.CLOCK_REALTIME, &ts) catch |err| switch (err) { + error.UnsupportedClock, error.Unexpected => return 0, // "Precision of timing depends on hardware and OS". + }; + return (@as(i128, ts.tv_sec) * ns_per_s) + ts.tv_nsec; } -/// Multiples of a base unit (nanoseconds) -pub const nanosecond = 1; -pub const microsecond = 1000 * nanosecond; -pub const millisecond = 1000 * microsecond; -pub const second = 1000 * millisecond; -pub const minute = 60 * second; -pub const hour = 60 * minute; +// Divisions of a nanosecond. +pub const ns_per_us = 1000; +pub const ns_per_ms = 1000 * ns_per_us; +pub const ns_per_s = 1000 * ns_per_ms; +pub const ns_per_min = 60 * ns_per_s; +pub const ns_per_hour = 60 * ns_per_min; +pub const ns_per_day = 24 * ns_per_hour; +pub const ns_per_week = 7 * ns_per_day; -/// Divisions of a second -pub const ns_per_s = 1000000000; -pub const us_per_s = 1000000; +// Divisions of a microsecond. +pub const us_per_ms = 1000; +pub const us_per_s = 1000 * us_per_ms; +pub const us_per_min = 60 * us_per_s; +pub const us_per_hour = 60 * us_per_min; +pub const us_per_day = 24 * us_per_hour; +pub const us_per_week = 7 * us_per_day; + +// Divisions of a millisecond. pub const ms_per_s = 1000; -pub const cs_per_s = 100; +pub const ms_per_min = 60 * ms_per_s; +pub const ms_per_hour = 60 * ms_per_min; +pub const ms_per_day = 24 * ms_per_hour; +pub const ms_per_week = 7 * ms_per_day; -/// Common time divisions +// Divisions of a second. pub const s_per_min = 60; pub const s_per_hour = s_per_min * 60; pub const s_per_day = s_per_hour * 24; @@ -119,12 +126,12 @@ pub const s_per_week = s_per_day * 7; /// A monotonic high-performance timer. /// Timer.start() must be called to initialize the struct, which captures -/// the counter frequency on windows and darwin, records the resolution, -/// and gives the user an opportunity to check for the existnece of -/// monotonic clocks without forcing them to check for error on each read. +/// the counter frequency on windows and darwin, records the resolution, +/// and gives the user an opportunity to check for the existnece of +/// monotonic clocks without forcing them to check for error on each read. /// .resolution is in nanoseconds on all platforms but .start_time's meaning -/// depends on the OS. On Windows and Darwin it is a hardware counter -/// value that requires calculation to convert to a meaninful unit. +/// depends on the OS. On Windows and Darwin it is a hardware counter +/// value that requires calculation to convert to a meaninful unit. pub const Timer = struct { ///if we used resolution's value when performing the /// performance counter calc on windows/darwin, it would @@ -137,43 +144,58 @@ pub const Timer = struct { resolution: u64, start_time: u64, - const Error = error{TimerUnsupported}; + pub const Error = error{TimerUnsupported}; - ///At some point we may change our minds on RAW, but for now we're - /// sticking with posix standard MONOTONIC. For more information, see: - /// https://github.com/ziglang/zig/pull/933 + /// At some point we may change our minds on RAW, but for now we're + /// sticking with posix standard MONOTONIC. For more information, see: + /// https://github.com/ziglang/zig/pull/933 const monotonic_clock_id = os.CLOCK_MONOTONIC; + /// Initialize the timer structure. - //This gives us an opportunity to grab the counter frequency in windows. - //On Windows: QueryPerformanceCounter will succeed on anything >= XP/2000. - //On Posix: CLOCK_MONOTONIC will only fail if the monotonic counter is not - // supported, or if the timespec pointer is out of bounds, which should be - // impossible here barring cosmic rays or other such occurrences of - // incredibly bad luck. - //On Darwin: This cannot fail, as far as I am able to tell. + /// Can only fail when running in a hostile environment that intentionally injects + /// error values into syscalls, such as using seccomp on Linux to intercept + /// `clock_gettime`. pub fn start() Error!Timer { - var self: Timer = undefined; - + // This gives us an opportunity to grab the counter frequency in windows. + // On Windows: QueryPerformanceCounter will succeed on anything >= XP/2000. + // On Posix: CLOCK_MONOTONIC will only fail if the monotonic counter is not + // supported, or if the timespec pointer is out of bounds, which should be + // impossible here barring cosmic rays or other such occurrences of + // incredibly bad luck. + // On Darwin: This cannot fail, as far as I am able to tell. if (is_windows) { - self.frequency = os.windows.QueryPerformanceFrequency(); - self.resolution = @divFloor(ns_per_s, self.frequency); - self.start_time = os.windows.QueryPerformanceCounter(); + const freq = os.windows.QueryPerformanceFrequency(); + return Timer{ + .frequency = freq, + .resolution = @divFloor(ns_per_s, freq), + .start_time = os.windows.QueryPerformanceCounter(), + }; } else if (comptime std.Target.current.isDarwin()) { - os.darwin.mach_timebase_info(&self.frequency); - self.resolution = @divFloor(self.frequency.numer, self.frequency.denom); - self.start_time = os.darwin.mach_absolute_time(); - } else { - //On Linux, seccomp can do arbitrary things to our ability to call - // syscalls, including return any errno value it wants and - // inconsistently throwing errors. Since we can't account for - // abuses of seccomp in a reasonable way, we'll assume that if - // seccomp is going to block us it will at least do so consistently - var ts: os.timespec = undefined; - os.clock_getres(monotonic_clock_id, &ts) catch return error.TimerUnsupported; - self.resolution = @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec); + var freq: os.darwin.mach_timebase_info_data = undefined; + os.darwin.mach_timebase_info(&freq); + return Timer{ + .frequency = freq, + .resolution = @divFloor(freq.numer, freq.denom), + .start_time = os.darwin.mach_absolute_time(), + }; + } else { + // On Linux, seccomp can do arbitrary things to our ability to call + // syscalls, including return any errno value it wants and + // inconsistently throwing errors. Since we can't account for + // abuses of seccomp in a reasonable way, we'll assume that if + // seccomp is going to block us it will at least do so consistently + var res: os.timespec = undefined; + os.clock_getres(monotonic_clock_id, &res) catch return error.TimerUnsupported; + + var ts: os.timespec = undefined; os.clock_gettime(monotonic_clock_id, &ts) catch return error.TimerUnsupported; - self.start_time = @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec); + + return Timer{ + .resolution = @intCast(u64, res.tv_sec) * ns_per_s + @intCast(u64, res.tv_nsec), + .start_time = @intCast(u64, ts.tv_sec) * ns_per_s + @intCast(u64, ts.tv_nsec), + .frequency = {}, + }; } return self; @@ -226,7 +248,6 @@ test "sleep" { } test "timestamp" { - const ns_per_ms = (ns_per_s / ms_per_s); const margin = ns_per_ms * 50; const time_0 = milliTimestamp(); @@ -237,7 +258,6 @@ test "timestamp" { } test "Timer" { - const ns_per_ms = (ns_per_s / ms_per_s); const margin = ns_per_ms * 150; var timer = try Timer.start(); diff --git a/lib/std/time/epoch.zig b/lib/std/time/epoch.zig index fc031521a5..126c4fceb7 100644 --- a/lib/std/time/epoch.zig +++ b/lib/std/time/epoch.zig @@ -1,15 +1,26 @@ -/// Epoch reference times in terms of their difference from -/// posix epoch in seconds. -pub const posix = 0; //Jan 01, 1970 AD -pub const dos = 315532800; //Jan 01, 1980 AD -pub const ios = 978307200; //Jan 01, 2001 AD -pub const openvms = -3506716800; //Nov 17, 1858 AD -pub const zos = -2208988800; //Jan 01, 1900 AD -pub const windows = -11644473600; //Jan 01, 1601 AD -pub const amiga = 252460800; //Jan 01, 1978 AD -pub const pickos = -63244800; //Dec 31, 1967 AD -pub const gps = 315964800; //Jan 06, 1980 AD -pub const clr = -62135769600; //Jan 01, 0001 AD +//! Epoch reference times in terms of their difference from +//! UTC 1970-01-01 in seconds. + +/// Jan 01, 1970 AD +pub const posix = 0; +/// Jan 01, 1980 AD +pub const dos = 315532800; +/// Jan 01, 2001 AD +pub const ios = 978307200; +/// Nov 17, 1858 AD +pub const openvms = -3506716800; +/// Jan 01, 1900 AD +pub const zos = -2208988800; +/// Jan 01, 1601 AD +pub const windows = -11644473600; +/// Jan 01, 1978 AD +pub const amiga = 252460800; +/// Dec 31, 1967 AD +pub const pickos = -63244800; +/// Jan 06, 1980 AD +pub const gps = 315964800; +/// Jan 01, 0001 AD +pub const clr = -62135769600; pub const unix = posix; pub const android = posix;