diff options
Diffstat (limited to 'system.old/libraries/datetime/time.zig')
| -rw-r--r-- | system.old/libraries/datetime/time.zig | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/system.old/libraries/datetime/time.zig b/system.old/libraries/datetime/time.zig new file mode 100644 index 0000000..9634ace --- /dev/null +++ b/system.old/libraries/datetime/time.zig @@ -0,0 +1,77 @@ +//! 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); +} |
