| author | |
| committer | |
| log | cd783ccfc1f17a23f96512d337b2d5d7b10787c7 |
| tree | a545d28f6e4ae35605542f86bcc5f37380698590 |
| parent | dcf876ca97b391153bdaa72b21601f76b80e00e1 |
4 files changed, 94 insertions(+), 12 deletions(-)
licenses.txt+1| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | MIT: | 1 | MIT: |
| 2 | = https://spdx.org/licenses/MIT | 2 | = https://spdx.org/licenses/MIT |
| 3 | - This | 3 | - This |
| 4 | - git https://github.com/nektro/zig-expect | ||
| 4 | - git https://github.com/nektro/zig-extras | 5 | - git https://github.com/nektro/zig-extras |
test.zig+57| ... | @@ -1,6 +1,7 @@ | ... | @@ -1,6 +1,7 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const string = []const u8; | 2 | const string = []const u8; |
| 3 | const time = @import("time"); | 3 | const time = @import("time"); |
| 4 | const expect = @import("expect").expect; | ||
| 4 | 5 | ||
| 5 | pub fn main() !void { | 6 | pub fn main() !void { |
| 6 | std.log.info("All your codebase are belong to us.", .{}); | 7 | std.log.info("All your codebase are belong to us.", .{}); |
| ... | @@ -158,3 +159,59 @@ test { | ... | @@ -158,3 +159,59 @@ test { |
| 158 | t = t.addYears(1); | 159 | t = t.addYears(1); |
| 159 | try expectFmt(t, "YYYY-MM-DD hh:mm:ss A z", "2013-03-01 08:09:22 AM UTC"); | 160 | try expectFmt(t, "YYYY-MM-DD hh:mm:ss A z", "2013-03-01 08:09:22 AM UTC"); |
| 160 | } | 161 | } |
| 162 | |||
| 163 | // src/test/moment/add_subtract.js | ||
| 164 | test { | ||
| 165 | // var a = moment(), | ||
| 166 | // b, | ||
| 167 | // c, | ||
| 168 | // d; | ||
| 169 | // a.year(2011); | ||
| 170 | // a.month(9); | ||
| 171 | // a.date(12); | ||
| 172 | // a.hours(6); | ||
| 173 | // a.minutes(7); | ||
| 174 | // a.seconds(8); | ||
| 175 | // a.milliseconds(500); | ||
| 176 | |||
| 177 | // assert.equal(a.add({ ms: 50 }).milliseconds(), 550, 'Add milliseconds'); | ||
| 178 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addMs(50).ms).toEqual(550); | ||
| 179 | // assert.equal(a.add({ s: 1 }).seconds(), 9, 'Add seconds'); | ||
| 180 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addSecs(1).seconds).toEqual(9); | ||
| 181 | // assert.equal(a.add({ m: 1 }).minutes(), 8, 'Add minutes'); | ||
| 182 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addMins(1).minutes).toEqual(8); | ||
| 183 | // assert.equal(a.add({ h: 1 }).hours(), 7, 'Add hours'); | ||
| 184 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addHours(1).hours).toEqual(7); | ||
| 185 | // assert.equal(a.add({ d: 1 }).date(), 13, 'Add date'); | ||
| 186 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addDays(1).days).toEqual(12); | ||
| 187 | // assert.equal(a.add({ w: 1 }).date(), 20, 'Add week'); | ||
| 188 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addWeeks(1).days).toEqual(18); //TODO: | ||
| 189 | // assert.equal(a.add({ M: 1 }).month(), 10, 'Add month'); | ||
| 190 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addMonths(1).months).toEqual(10); | ||
| 191 | // assert.equal(a.add({ y: 1 }).year(), 2012, 'Add year'); | ||
| 192 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addYears(1).years).toEqual(2012); | ||
| 193 | // assert.equal(a.add({ Q: 1 }).month(), 1, 'Add quarter'); | ||
| 194 | try expect(time.DateTime.init(2011, 9, 11, 6, 7, 8, 500).addQuarters(1).months).toEqual(0); //TODO: | ||
| 195 | |||
| 196 | // b = moment([2010, 0, 31]).add({ M: 1 }); | ||
| 197 | // c = moment([2010, 1, 28]).subtract({ M: 1 }); | ||
| 198 | // d = moment([2010, 1, 28]).subtract({ Q: 1 }); | ||
| 199 | |||
| 200 | // assert.equal(b.month(), 1, 'add month, jan 31st to feb 28th'); | ||
| 201 | try expect(time.DateTime.init(2010, 0, 30, 0, 0, 0, 0).addMonths(1).toISOString()).toEqualString("2010-02-28T00:00:00Z"); | ||
| 202 | try expect(time.DateTime.init(2010, 0, 30, 0, 0, 0, 0).addMonths(1).months).toEqual(1); | ||
| 203 | try expect(time.DateTime.init(2009, 11, 30, 0, 0, 0, 0).addMonths(2).toISOString()).toEqualString("2010-02-28T00:00:00Z"); | ||
| 204 | try expect(time.DateTime.init(2009, 11, 30, 0, 0, 0, 0).addMonths(2).months).toEqual(1); | ||
| 205 | // assert.equal(b.date(), 28, 'add month, jan 31st to feb 28th'); | ||
| 206 | try expect(time.DateTime.init(2010, 0, 30, 0, 0, 0, 0).addMonths(1).days).toEqual(27); | ||
| 207 | // assert.equal(c.month(), 0, 'subtract month, feb 28th to jan 28th'); | ||
| 208 | // try expect(time.DateTime.init(2010, 1, 27, 0, 0, 0, 0).subMonths(1).months).toEqual(0); | ||
| 209 | // assert.equal(c.date(), 28, 'subtract month, feb 28th to jan 28th'); | ||
| 210 | // try expect(time.DateTime.init(2010, 1, 27, 0, 0, 0, 0).subMonths(1).days).toEqual(28); | ||
| 211 | // assert.equal(d.month(), 10, 'subtract quarter, feb 28th 2010 to nov 28th 2009'); | ||
| 212 | // try expect(time.DateTime.init(2010, 1, 27, 0, 0, 0, 0).subQuarters(1).months).toEqual(10); | ||
| 213 | // assert.equal(d.date(), 28, 'subtract quarter, feb 28th 2010 to nov 28th 2009'); | ||
| 214 | // try expect(time.DateTime.init(2010, 1, 27, 0, 0, 0, 0).subQuarters(1).days).toEqual(28); | ||
| 215 | // assert.equal(d.year(), 2009, 'subtract quarter, feb 28th 2010 to nov 28th 2009'); | ||
| 216 | // try expect(time.DateTime.init(2010, 1, 27, 0, 0, 0, 0).subQuarters(1).years).toEqual(2009); | ||
| 217 | } |
time.zig+34-12| ... | @@ -24,14 +24,15 @@ pub const DateTime = struct { | ... | @@ -24,14 +24,15 @@ pub const DateTime = struct { |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | /// Caller asserts that this is > epoch | 26 | /// Caller asserts that this is > epoch |
| 27 | pub fn init(year: u16, month: u16, day: u16, hr: u16, min: u16, sec: u16) Self { | 27 | pub fn init(year: u16, month: u16, day: u16, hr: u16, min: u16, sec: u16, ms: u16) Self { |
| 28 | return epoch_unix | 28 | return epoch_unix |
| 29 | .addYears(year - epoch_unix.years) | 29 | .addYears(year - epoch_unix.years) |
| 30 | .addMonths(month) | 30 | .addMonths(month) |
| 31 | .addDays(day) | 31 | .addDays(day) |
| 32 | .addHours(hr) | 32 | .addHours(hr) |
| 33 | .addMins(min) | 33 | .addMins(min) |
| 34 | .addSecs(sec); | 34 | .addSecs(sec) |
| 35 | .addMs(ms); | ||
| 35 | } | 36 | } |
| 36 | 37 | ||
| 37 | pub fn now() Self { | 38 | pub fn now() Self { |
| ... | @@ -49,6 +50,16 @@ pub const DateTime = struct { | ... | @@ -49,6 +50,16 @@ pub const DateTime = struct { |
| 49 | .timezone = .UTC, | 50 | .timezone = .UTC, |
| 50 | }; | 51 | }; |
| 51 | 52 | ||
| 53 | pub fn toISOString(self: Self) [20]u8 { | ||
| 54 | // "2021-10-21T23:20:30Z" | ||
| 55 | var result: [20]u8 = @splat(0); | ||
| 56 | var fbs = std.io.fixedBufferStream(&result); | ||
| 57 | self.format("YYYY-MM-DD HH:mm:ss", .{}, fbs.writer()) catch unreachable; | ||
| 58 | result[10] = 'T'; | ||
| 59 | result[19] = 'Z'; | ||
| 60 | return result; | ||
| 61 | } | ||
| 62 | |||
| 52 | pub fn eql(self: Self, other: Self) bool { | 63 | pub fn eql(self: Self, other: Self) bool { |
| 53 | return self.ms == other.ms and | 64 | return self.ms == other.ms and |
| 54 | self.seconds == other.seconds and | 65 | self.seconds == other.seconds and |
| ... | @@ -120,7 +131,7 @@ pub const DateTime = struct { | ... | @@ -120,7 +131,7 @@ pub const DateTime = struct { |
| 120 | { | 131 | { |
| 121 | const month_len = result.daysThisMonth(); | 132 | const month_len = result.daysThisMonth(); |
| 122 | if (result.days + input > month_len) { | 133 | if (result.days + input > month_len) { |
| 123 | const left = month_len - result.days; | 134 | const left = month_len -| result.days; |
| 124 | input -= left; | 135 | input -= left; |
| 125 | result.months += 1; | 136 | result.months += 1; |
| 126 | result.days = 0; | 137 | result.days = 0; |
| ... | @@ -146,15 +157,21 @@ pub const DateTime = struct { | ... | @@ -146,15 +157,21 @@ pub const DateTime = struct { |
| 146 | return result; | 157 | return result; |
| 147 | } | 158 | } |
| 148 | 159 | ||
| 160 | pub fn addWeeks(self: Self, count: u64) Self { | ||
| 161 | if (count == 0) return self; | ||
| 162 | return self.addDays(7).addWeeks(count - 1); | ||
| 163 | } | ||
| 164 | |||
| 149 | pub fn addMonths(self: Self, count: u64) Self { | 165 | pub fn addMonths(self: Self, count: u64) Self { |
| 150 | if (count == 0) return self; | 166 | if (count == 0) return self; |
| 151 | var result = self; | 167 | var result = self; |
| 152 | var input = count; | 168 | var input = count; |
| 153 | while (input > 0) { | 169 | result.years += @intCast(input / 12); |
| 154 | const new = result.addDays(result.daysThisMonth()); | 170 | input %= 12; |
| 155 | result = new; | 171 | result.months += @intCast(input); |
| 156 | input -= 1; | 172 | if (result.months >= 12) result.years += 1; |
| 157 | } | 173 | result.months %= 12; |
| 174 | result.days = @min(result.days, result.daysInMonth(result.months) - 1); | ||
| 158 | return result; | 175 | return result; |
| 159 | } | 176 | } |
| 160 | 177 | ||
| ... | @@ -166,6 +183,11 @@ pub const DateTime = struct { | ... | @@ -166,6 +183,11 @@ pub const DateTime = struct { |
| 166 | return result; | 183 | return result; |
| 167 | } | 184 | } |
| 168 | 185 | ||
| 186 | pub fn addQuarters(self: Self, count: u64) Self { | ||
| 187 | if (count == 0) return self; | ||
| 188 | return self.addMonths(3).addQuarters(count - 1); | ||
| 189 | } | ||
| 190 | |||
| 169 | pub fn isLeapYear(self: Self) bool { | 191 | pub fn isLeapYear(self: Self) bool { |
| 170 | return time.isLeapYear(self.years); | 192 | return time.isLeapYear(self.years); |
| 171 | } | 193 | } |
| ... | @@ -199,10 +221,10 @@ pub const DateTime = struct { | ... | @@ -199,10 +221,10 @@ pub const DateTime = struct { |
| 199 | pub fn toUnixMilli(self: Self) u64 { | 221 | pub fn toUnixMilli(self: Self) u64 { |
| 200 | var res: u64 = 0; | 222 | var res: u64 = 0; |
| 201 | res += self.ms; | 223 | res += self.ms; |
| 202 | res += @as(u64, self.seconds) * std.time.ms_per_s; | 224 | res += @as(u64, self.seconds) * ms_per_s; |
| 203 | res += @as(u64, self.minutes) * std.time.ms_per_min; | 225 | res += @as(u64, self.minutes) * ms_per_min; |
| 204 | res += @as(u64, self.hours) * std.time.ms_per_hour; | 226 | res += @as(u64, self.hours) * ms_per_hour; |
| 205 | res += self.daysSinceEpoch() * std.time.ms_per_day; | 227 | res += self.daysSinceEpoch() * ms_per_day; |
| 206 | return res; | 228 | return res; |
| 207 | } | 229 | } |
| 208 | 230 |
zig.mod+2| ... | @@ -6,3 +6,5 @@ description: A date and time parsing and formatting library for Zig. | ... | @@ -6,3 +6,5 @@ description: A date and time parsing and formatting library for Zig. |
| 6 | min_zig_version: 0.11.0-dev.1681+0bb178bbb | 6 | min_zig_version: 0.11.0-dev.1681+0bb178bbb |
| 7 | dependencies: | 7 | dependencies: |
| 8 | - src: git https://github.com/nektro/zig-extras | 8 | - src: git https://github.com/nektro/zig-extras |
| 9 | root_dependencies: | ||
| 10 | - src: git https://github.com/nektro/zig-expect |