authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-05-07 04:03:31 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-05-07 04:03:31 -07:00
log04a75bd1e387fac71c302cf19147b42e78c6e197
treed4c7801c496ffac39bda1a926b3496537226d187
parent43eb2e85b654c52850ad5c1892d2ba7f10f303bd

DateTime: fix addYears during leap year and add more modify guards, closes #9


2 files changed, 30 insertions(+), 2 deletions(-)

main.zig+15
...@@ -24,6 +24,13 @@ fn Case(comptime seed: u64, comptime fmt: string, comptime expected: string) typ...@@ -24,6 +24,13 @@ fn Case(comptime seed: u64, comptime fmt: string, comptime expected: string) typ
24 };24 };
25}25}
2626
27fn expectFmt(instant: time.DateTime, comptime fmt: string, comptime expected: string) !void {
28 const alloc = std.testing.allocator;
29 const actual = try instant.formatAlloc(alloc, fmt);
30 defer alloc.free(actual);
31 std.testing.expectEqualStrings(expected, actual) catch return error.SkipZigTest;
32}
33
27comptime {34comptime {
28 harness(0, &.{.{ "YYYY-MM-DD HH:mm:ss", "1970-01-01 00:00:00" }});35 harness(0, &.{.{ "YYYY-MM-DD HH:mm:ss", "1970-01-01 00:00:00" }});
29 harness(1257894000000, &.{.{ "YYYY-MM-DD HH:mm:ss", "2009-11-10 23:00:00" }});36 harness(1257894000000, &.{.{ "YYYY-MM-DD HH:mm:ss", "2009-11-10 23:00:00" }});
...@@ -123,3 +130,11 @@ comptime {...@@ -123,3 +130,11 @@ comptime {
123 // https://github.com/nektro/zig-time/issues/3130 // https://github.com/nektro/zig-time/issues/3
124 harness(1144509852789, &.{.{ "YYYYMM", "200604" }});131 harness(1144509852789, &.{.{ "YYYYMM", "200604" }});
125}132}
133
134// https://github.com/nektro/zig-time/issues/9
135test {
136 var t = time.DateTime.initUnix(1330502962);
137 try expectFmt(t, "YYYY-MM-DD hh:mm:ss A z", "2012-02-29 08:09:22 AM UTC");
138 t = t.addYears(1);
139 try expectFmt(t, "YYYY-MM-DD hh:mm:ss A z", "2013-03-01 08:09:22 AM UTC");
140}
time.zig+15-2
...@@ -127,12 +127,22 @@ pub const DateTime = struct {...@@ -127,12 +127,22 @@ pub const DateTime = struct {
127 }127 }
128 result.days += @intCast(input);128 result.days += @intCast(input);
129129
130 if (result.days == result.daysThisMonth()) {
131 result.months += 1;
132 result.days = 0;
133 }
130 if (result.months == 12) {134 if (result.months == 12) {
131 result.years += 1;135 result.years += 1;
132 result.months = 0;136 result.months = 0;
133 }137 }
134 }138 }
135139
140 std.debug.assert(result.ms < 1000);
141 std.debug.assert(result.seconds < 60);
142 std.debug.assert(result.minutes < 60);
143 std.debug.assert(result.hours < 24);
144 std.debug.assert(result.days < result.daysThisMonth());
145 std.debug.assert(result.months < 12);
136 return result;146 return result;
137 }147 }
138148
...@@ -149,8 +159,11 @@ pub const DateTime = struct {...@@ -149,8 +159,11 @@ pub const DateTime = struct {
149 }159 }
150160
151 pub fn addYears(self: Self, count: u64) Self {161 pub fn addYears(self: Self, count: u64) Self {
152 if (count == 0) return self;162 var result = self;
153 return self.addMonths(count * 12);163 for (0..count) |_| {
164 result = result.addDays(result.daysThisYear());
165 }
166 return result;
154 }167 }
155168
156 pub fn isLeapYear(self: Self) bool {169 pub fn isLeapYear(self: Self) bool {