//! Time operations const sys = @import("sys"); const types = @import("types.zig"); const ERROR_RESULT: u64 = @bitCast(@as(i64, -1)); const SECONDS_PER_DAY: u64 = 86400; const SECONDS_PER_HOUR: u64 = 3600; const SECONDS_PER_MINUTE: u64 = 60; const DAYS_PER_4_YEARS: u64 = 1461; const DAYS_NORMAL = [_]u64{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; const DAYS_LEAP = [_]u64{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; pub fn now() ?u64 { const result = sys.syscall(.gettime, .{}); if (result == ERROR_RESULT) { return null; } return result; } pub fn parts(timestamp: u64) types.DateTime { const days_since_epoch = timestamp / SECONDS_PER_DAY; const seconds_today = timestamp % SECONDS_PER_DAY; const hours = seconds_today / SECONDS_PER_HOUR; const minutes = (seconds_today % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE; const seconds = seconds_today % SECONDS_PER_MINUTE; var year: u64 = 1970; var remaining_days = days_since_epoch; const four_year_cycles = remaining_days / DAYS_PER_4_YEARS; year += four_year_cycles * 4; remaining_days = remaining_days % DAYS_PER_4_YEARS; while (remaining_days >= 365) { const is_leap = isLeapYear(year); const days_this_year: u64 = if (is_leap) 366 else 365; if (remaining_days >= days_this_year) { remaining_days -= days_this_year; year += 1; } else { break; } } const is_leap = isLeapYear(year); const days_in_months = if (is_leap) DAYS_LEAP else DAYS_NORMAL; var month: u8 = 1; var day: u64 = remaining_days + 1; for (days_in_months, 0..) |days, m| { if (day <= days) { month = @intCast(m + 1); break; } day -= days; } return types.DateTime{ .year = year, .month = month, .day = @intCast(day), .hour = @intCast(hours), .minute = @intCast(minutes), .second = @intCast(seconds), }; } fn isLeapYear(year: u64) bool { return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0); }