| ... | ... | @@ -13,18 +13,16 @@ pub const DateTime = struct { |
| 13 | 13 | years: u16, |
| 14 | 14 | timezone: TimeZone, |
| 15 | 15 | |
| 16 | | const Self = @This(); |
| 17 | | |
| 18 | | pub fn initUnixMs(unix: u64) Self { |
| 16 | pub fn initUnixMs(unix: u64) DateTime { |
| 19 | 17 | return epoch_unix.addMs(unix); |
| 20 | 18 | } |
| 21 | 19 | |
| 22 | | pub fn initUnix(unix: u64) Self { |
| 20 | pub fn initUnix(unix: u64) DateTime { |
| 23 | 21 | return epoch_unix.addSecs(unix); |
| 24 | 22 | } |
| 25 | 23 | |
| 26 | 24 | /// Caller asserts that this is > epoch |
| 27 | | pub fn init(year: u16, month: u16, day: u16, hr: u16, min: u16, sec: u16, ms: u16) Self { |
| 25 | pub fn init(year: u16, month: u16, day: u16, hr: u16, min: u16, sec: u16, ms: u16) DateTime { |
| 28 | 26 | return epoch_unix |
| 29 | 27 | .addYears(year - epoch_unix.years) |
| 30 | 28 | .addMonths(month) |
| ... | ... | @@ -35,11 +33,11 @@ pub const DateTime = struct { |
| 35 | 33 | .addMs(ms); |
| 36 | 34 | } |
| 37 | 35 | |
| 38 | | pub fn now() Self { |
| 36 | pub fn now() DateTime { |
| 39 | 37 | return initUnixMs(@intCast(std.time.milliTimestamp())); |
| 40 | 38 | } |
| 41 | 39 | |
| 42 | | pub const epoch_unix = Self{ |
| 40 | pub const epoch_unix = DateTime{ |
| 43 | 41 | .ms = 0, |
| 44 | 42 | .seconds = 0, |
| 45 | 43 | .minutes = 0, |
| ... | ... | @@ -50,7 +48,7 @@ pub const DateTime = struct { |
| 50 | 48 | .timezone = .UTC, |
| 51 | 49 | }; |
| 52 | 50 | |
| 53 | | pub fn toISOString(self: Self) [20]u8 { |
| 51 | pub fn toISOString(self: DateTime) [20]u8 { |
| 54 | 52 | // "2021-10-21T23:20:30Z" |
| 55 | 53 | var result: [20]u8 = @splat(0); |
| 56 | 54 | var fbs = std.io.fixedBufferStream(&result); |
| ... | ... | @@ -60,7 +58,7 @@ pub const DateTime = struct { |
| 60 | 58 | return result; |
| 61 | 59 | } |
| 62 | 60 | |
| 63 | | pub fn eql(self: Self, other: Self) bool { |
| 61 | pub fn eql(self: DateTime, other: DateTime) bool { |
| 64 | 62 | return self.ms == other.ms and |
| 65 | 63 | self.seconds == other.seconds and |
| 66 | 64 | self.minutes == other.minutes and |
| ... | ... | @@ -72,35 +70,35 @@ pub const DateTime = struct { |
| 72 | 70 | self.weekday == other.weekday; |
| 73 | 71 | } |
| 74 | 72 | |
| 75 | | pub fn addMs(self: Self, count: u64) Self { |
| 73 | pub fn addMs(self: DateTime, count: u64) DateTime { |
| 76 | 74 | if (count == 0) return self; |
| 77 | 75 | var result = self; |
| 78 | 76 | result.ms += @intCast(count % 1000); |
| 79 | 77 | return result.addSecs(count / 1000); |
| 80 | 78 | } |
| 81 | 79 | |
| 82 | | pub fn addSecs(self: Self, count: u64) Self { |
| 80 | pub fn addSecs(self: DateTime, count: u64) DateTime { |
| 83 | 81 | if (count == 0) return self; |
| 84 | 82 | var result = self; |
| 85 | 83 | result.seconds += @intCast(count % 60); |
| 86 | 84 | return result.addMins(count / 60); |
| 87 | 85 | } |
| 88 | 86 | |
| 89 | | pub fn addMins(self: Self, count: u64) Self { |
| 87 | pub fn addMins(self: DateTime, count: u64) DateTime { |
| 90 | 88 | if (count == 0) return self; |
| 91 | 89 | var result = self; |
| 92 | 90 | result.minutes += @intCast(count % 60); |
| 93 | 91 | return result.addHours(count / 60); |
| 94 | 92 | } |
| 95 | 93 | |
| 96 | | pub fn addHours(self: Self, count: u64) Self { |
| 94 | pub fn addHours(self: DateTime, count: u64) DateTime { |
| 97 | 95 | if (count == 0) return self; |
| 98 | 96 | var result = self; |
| 99 | 97 | result.hours += @intCast(count % 24); |
| 100 | 98 | return result.addDays(count / 24); |
| 101 | 99 | } |
| 102 | 100 | |
| 103 | | pub fn addDays(self: Self, count: u64) Self { |
| 101 | pub fn addDays(self: DateTime, count: u64) DateTime { |
| 104 | 102 | if (count == 0) return self; |
| 105 | 103 | var result = self; |
| 106 | 104 | var input = count; |
| ... | ... | @@ -157,12 +155,12 @@ pub const DateTime = struct { |
| 157 | 155 | return result; |
| 158 | 156 | } |
| 159 | 157 | |
| 160 | | pub fn addWeeks(self: Self, count: u64) Self { |
| 158 | pub fn addWeeks(self: DateTime, count: u64) DateTime { |
| 161 | 159 | if (count == 0) return self; |
| 162 | 160 | return self.addDays(7).addWeeks(count - 1); |
| 163 | 161 | } |
| 164 | 162 | |
| 165 | | pub fn addMonths(self: Self, count: u64) Self { |
| 163 | pub fn addMonths(self: DateTime, count: u64) DateTime { |
| 166 | 164 | if (count == 0) return self; |
| 167 | 165 | var result = self; |
| 168 | 166 | var input = count; |
| ... | ... | @@ -175,7 +173,7 @@ pub const DateTime = struct { |
| 175 | 173 | return result; |
| 176 | 174 | } |
| 177 | 175 | |
| 178 | | pub fn addYears(self: Self, count: u64) Self { |
| 176 | pub fn addYears(self: DateTime, count: u64) DateTime { |
| 179 | 177 | var result = self; |
| 180 | 178 | for (0..count) |_| { |
| 181 | 179 | result = result.addDays(result.daysThisYear()); |
| ... | ... | @@ -183,28 +181,28 @@ pub const DateTime = struct { |
| 183 | 181 | return result; |
| 184 | 182 | } |
| 185 | 183 | |
| 186 | | pub fn addQuarters(self: Self, count: u64) Self { |
| 184 | pub fn addQuarters(self: DateTime, count: u64) DateTime { |
| 187 | 185 | if (count == 0) return self; |
| 188 | 186 | return self.addMonths(3).addQuarters(count - 1); |
| 189 | 187 | } |
| 190 | 188 | |
| 191 | | pub fn isLeapYear(self: Self) bool { |
| 189 | pub fn isLeapYear(self: DateTime) bool { |
| 192 | 190 | return time.isLeapYear(self.years); |
| 193 | 191 | } |
| 194 | 192 | |
| 195 | | pub fn daysThisYear(self: Self) u16 { |
| 193 | pub fn daysThisYear(self: DateTime) u16 { |
| 196 | 194 | return time.daysInYear(self.years); |
| 197 | 195 | } |
| 198 | 196 | |
| 199 | | pub fn daysThisMonth(self: Self) u16 { |
| 197 | pub fn daysThisMonth(self: DateTime) u16 { |
| 200 | 198 | return self.daysInMonth(self.months); |
| 201 | 199 | } |
| 202 | 200 | |
| 203 | | fn daysInMonth(self: Self, month: u16) u16 { |
| 201 | fn daysInMonth(self: DateTime, month: u16) u16 { |
| 204 | 202 | return time.daysInMonth(self.years, month); |
| 205 | 203 | } |
| 206 | 204 | |
| 207 | | pub fn dayOfThisYear(self: Self) u16 { |
| 205 | pub fn dayOfThisYear(self: DateTime) u16 { |
| 208 | 206 | var ret: u16 = 0; |
| 209 | 207 | for (0..self.months) |item| { |
| 210 | 208 | ret += self.daysInMonth(@intCast(item)); |
| ... | ... | @@ -213,12 +211,12 @@ pub const DateTime = struct { |
| 213 | 211 | return ret; |
| 214 | 212 | } |
| 215 | 213 | |
| 216 | | pub fn toUnix(self: Self) u64 { |
| 214 | pub fn toUnix(self: DateTime) u64 { |
| 217 | 215 | const x = self.toUnixMilli(); |
| 218 | 216 | return x / 1000; |
| 219 | 217 | } |
| 220 | 218 | |
| 221 | | pub fn toUnixMilli(self: Self) u64 { |
| 219 | pub fn toUnixMilli(self: DateTime) u64 { |
| 222 | 220 | var res: u64 = 0; |
| 223 | 221 | res += self.ms; |
| 224 | 222 | res += @as(u64, self.seconds) * ms_per_s; |
| ... | ... | @@ -228,7 +226,7 @@ pub const DateTime = struct { |
| 228 | 226 | return res; |
| 229 | 227 | } |
| 230 | 228 | |
| 231 | | fn daysSinceEpoch(self: Self) u64 { |
| 229 | fn daysSinceEpoch(self: DateTime) u64 { |
| 232 | 230 | var res: u64 = 0; |
| 233 | 231 | res += self.days; |
| 234 | 232 | for (0..self.years - epoch_unix.years) |i| res += time.daysInYear(@intCast(i)); |
| ... | ... | @@ -237,7 +235,7 @@ pub const DateTime = struct { |
| 237 | 235 | } |
| 238 | 236 | |
| 239 | 237 | /// fmt is based on https://momentjs.com/docs/#/displaying/format/ |
| 240 | | pub fn format(self: Self, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 238 | pub fn format(self: DateTime, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 241 | 239 | _ = options; |
| 242 | 240 | |
| 243 | 241 | if (fmt.len == 0) @compileError("DateTime: format string can't be empty"); |
| ... | ... | @@ -344,7 +342,7 @@ pub const DateTime = struct { |
| 344 | 342 | } |
| 345 | 343 | } |
| 346 | 344 | |
| 347 | | pub fn formatAlloc(self: Self, alloc: std.mem.Allocator, comptime fmt: string) !string { |
| 345 | pub fn formatAlloc(self: DateTime, alloc: std.mem.Allocator, comptime fmt: string) !string { |
| 348 | 346 | var list = std.ArrayList(u8).init(alloc); |
| 349 | 347 | defer list.deinit(); |
| 350 | 348 | |
| ... | ... | @@ -404,18 +402,18 @@ pub const DateTime = struct { |
| 404 | 402 | X, // unix |
| 405 | 403 | }; |
| 406 | 404 | |
| 407 | | pub fn since(self: Self, other_in_the_past: Self) Duration { |
| 405 | pub fn since(self: DateTime, other_in_the_past: DateTime) Duration { |
| 408 | 406 | return Duration{ |
| 409 | 407 | .ms = self.toUnixMilli() - other_in_the_past.toUnixMilli(), |
| 410 | 408 | }; |
| 411 | 409 | } |
| 412 | 410 | |
| 413 | | pub fn era(self: Self) Era { |
| 411 | pub fn era(self: DateTime) Era { |
| 414 | 412 | if (self.years >= 0) return .AD; |
| 415 | 413 | @compileError("TODO"); |
| 416 | 414 | } |
| 417 | 415 | |
| 418 | | pub fn weekday(self: Self) WeekDay { |
| 416 | pub fn weekday(self: DateTime) WeekDay { |
| 419 | 417 | var i = self.daysSinceEpoch() % 7; |
| 420 | 418 | var result = WeekDay.Thu; // weekday of epoch_unix |
| 421 | 419 | while (i > 0) : (i -= 1) { |