diff options
| author | Bobby <[email protected]> | 2026-02-15 21:44:15 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-02-15 21:44:15 +0530 |
| commit | 85ea61c58c96b5ae052e40fce777f8e3d2b7ca62 (patch) | |
| tree | ab7e84dd64e8600d6c102ed12a8f598962b88aff /system/libraries/format/date.zig | |
| parent | 71e5250b05d06505612dc5a0fcf3d25fb5277cf5 (diff) | |
| download | akiba-85ea61c58c96b5ae052e40fce777f8e3d2b7ca62.tar.xz akiba-85ea61c58c96b5ae052e40fce777f8e3d2b7ca62.zip | |
feat: Add core libraries for color, formatting, I/O, string manipulation, and memory utilities
Diffstat (limited to 'system/libraries/format/date.zig')
| -rw-r--r-- | system/libraries/format/date.zig | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/system/libraries/format/date.zig b/system/libraries/format/date.zig new file mode 100644 index 0000000..d90adec --- /dev/null +++ b/system/libraries/format/date.zig @@ -0,0 +1,108 @@ +//! Date formatting + +const int = @import("int.zig"); + +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 MONTH_NAMES = [_][]const u8{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +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 format(timestamp: u64, buf: []u8) []u8 { + if (timestamp == 0) { + const default = "01 Jan 1970 00:00"; + for (default, 0..) |c, i| { + buf[i] = c; + } + return buf[0..default.len]; + } + + 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; + + 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: usize = 0; + var day: u64 = remaining_days + 1; + + for (days_in_months, 0..) |days, m| { + if (day <= days) { + month = m; + break; + } + day -= days; + } + + var pos: usize = 0; + + if (day < 10) { + buf[pos] = '0'; + pos += 1; + } + const day_str = int.toStr(day, buf[pos..]); + pos += day_str.len; + + buf[pos] = ' '; + pos += 1; + + for (MONTH_NAMES[month]) |c| { + buf[pos] = c; + pos += 1; + } + + buf[pos] = ' '; + pos += 1; + + const year_str = int.toStr(year, buf[pos..]); + pos += year_str.len; + + buf[pos] = ' '; + pos += 1; + + if (hours < 10) { + buf[pos] = '0'; + pos += 1; + } + const hour_str = int.toStr(hours, buf[pos..]); + pos += hour_str.len; + + buf[pos] = ':'; + pos += 1; + + if (minutes < 10) { + buf[pos] = '0'; + pos += 1; + } + const min_str = int.toStr(minutes, buf[pos..]); + pos += min_str.len; + + return buf[0..pos]; +} + +fn isLeapYear(year: u64) bool { + return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0); +} |
