authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-10-24 22:45:44 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-10-24 22:45:44 -07:00
log94c354c7d789a8e37d08dc6e3885b62fb37bde23
treeea7fdcf18f4a92a8a213c5f4255ed75edb02dd2a
parent9efb79e6b09aba6bff5d5fafd7aba3e2e5a89907

implement final printer for unix timestamp


2 files changed, 53 insertions(+), 13 deletions(-)

main.zig+3
......@@ -116,5 +116,8 @@ comptime {
116116 .{ "z", "UTC" },
117117 .{ "Z", "+00:00" },
118118 .{ "ZZ", "+0000" },
119
120 .{ "x", "1144509852789" },
121 // .{ "X", "1144509852" },
119122 });
120123}
time.zig+50-13
......@@ -1,6 +1,7 @@
11const std = @import("std");
22const string = []const u8;
33const range = @import("range").range;
4const time = @This();
45
56pub const DateTime = struct {
67 ms: u16,
......@@ -161,16 +162,11 @@ pub const DateTime = struct {
161162 }
162163
163164 pub fn isLeapYear(self: Self) bool {
164 const y = self.years;
165 var ret = false;
166 if (y % 4 == 0) ret = true;
167 if (y % 100 == 0) ret = false;
168 if (y % 400 == 0) ret = true;
169 return ret;
165 return time.isLeapYear(self.years);
170166 }
171167
172168 pub fn daysThisYear(self: Self) u64 {
173 return if (self.isLeapYear()) 366 else 365;
169 return time.daysInYear(self.years);
174170 }
175171
176172 pub fn daysThisMonth(self: Self) u16 {
......@@ -178,10 +174,7 @@ pub const DateTime = struct {
178174 }
179175
180176 fn daysInMonth(self: Self, month: u16) u16 {
181 const norm = [12]u16{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
182 const leap = [12]u16{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
183 const month_days = if (!self.isLeapYear()) norm else leap;
184 return month_days[month];
177 return time.daysInMonth(self.years, month);
185178 }
186179
187180 fn incrementWeekday(self: *Self, count: u64) void {
......@@ -199,6 +192,29 @@ pub const DateTime = struct {
199192 return ret;
200193 }
201194
195 // pub fn toUnix(self: Self) u64 {
196 // const x = self.toUnix();
197 // return x / 1000;
198 // }
199
200 pub fn toUnixMilli(self: Self) u64 {
201 var res: u64 = 0;
202 res += self.ms;
203 res += @as(u64, self.seconds) * std.time.ms_per_s;
204 res += @as(u64, self.minutes) * std.time.ms_per_min;
205 res += @as(u64, self.hours) * std.time.ms_per_hour;
206 res += self.daysSinceEpoch() * std.time.ms_per_day;
207 return res;
208 }
209
210 fn daysSinceEpoch(self: Self) u64 {
211 var res: u64 = 0;
212 res += self.days;
213 for (range(self.years - epoch_unix.years)) |_, i| res += time.daysInYear(@intCast(u16, i));
214 for (range(self.months)) |_, i| res += self.daysInMonth(@intCast(u16, i));
215 return res;
216 }
217
202218 /// fmt is based on https://momentjs.com/docs/#/displaying/format/
203219 pub fn format(self: Self, comptime fmt: string, options: std.fmt.FormatOptions, writer: anytype) !void {
204220 _ = options;
......@@ -239,6 +255,7 @@ pub const DateTime = struct {
239255 .DDD => try writer.print("{}", .{self.dayOfThisYear() + 1}),
240256 .DDDo => try printOrdinal(writer, self.dayOfThisYear() + 1),
241257 .DDDD => try writer.print("{:0>3}", .{self.dayOfThisYear() + 1}),
258
242259 .d => try writer.print("{}", .{@enumToInt(self.weekday)}),
243260 .do => try printOrdinal(writer, @enumToInt(self.weekday)),
244261 .dd => try writer.writeAll(@tagName(self.weekday)[0..2]),
......@@ -283,7 +300,8 @@ pub const DateTime = struct {
283300 .Z => try writer.writeAll("+00:00"),
284301 .ZZ => try writer.writeAll("+0000"),
285302
286 else => @compileError("'" ++ @tagName(tag) ++ "' not currently supported"),
303 .x => try writer.print("{}", .{self.toUnixMilli()}),
304 // .X => try writer.print("{}", .{self.toUnix()}),
287305 }
288306 next = null;
289307 s = i;
......@@ -365,8 +383,8 @@ pub const DateTime = struct {
365383 z, // EST CST ... MST PST
366384 Z, // -07:00 -06:00 ... +06:00 +07:00
367385 ZZ, // -0700 -0600 ... +0600 +0700
368 X, // unix
369386 x, // unix milli
387 // X, // unix
370388 };
371389};
372390
......@@ -414,6 +432,25 @@ pub const Era = enum {
414432 AD,
415433};
416434
435pub fn isLeapYear(year: u16) bool {
436 var ret = false;
437 if (year % 4 == 0) ret = true;
438 if (year % 100 == 0) ret = false;
439 if (year % 400 == 0) ret = true;
440 return ret;
441}
442
443pub fn daysInYear(year: u16) u16 {
444 return if (isLeapYear(year)) 366 else 365;
445}
446
447fn daysInMonth(year: u16, month: u16) u16 {
448 const norm = [12]u16{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
449 const leap = [12]u16{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
450 const month_days = if (!isLeapYear(year)) norm else leap;
451 return month_days[month];
452}
453
417454fn printOrdinal(writer: anytype, num: u16) !void {
418455 try writer.print("{}", .{num});
419456 try writer.writeAll(switch (num) {