Compare commits

...

2 Commits

3 changed files with 157 additions and 0 deletions

View File

@ -1,5 +1,6 @@
const std = @import("std");
const debug = std.debug;
const mem = std.mem;
const testing = std.testing;
pub const Year = @import("year.zig").Year;
pub const Month = @import("month.zig").Month;
@ -181,6 +182,49 @@ pub const DateTime = struct {
const b = other.toTimestamp();
return if (a > b) .gt else if (a < b) .lt else .eq;
}
pub fn format(
self: Self,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
try writer.print("{s}-{d:0>2}-{d:0>2}", .{
self.year, @enumToInt(self.month), self.day,
});
if (self.hour) |h| {
try writer.print("T{d:0>2}", .{h});
if (self.minute) |m| {
try writer.print(":{d:0>2}", .{m});
if (self.second) |s| {
try writer.print(":{d:0>2}", .{s});
}
}
}
try writer.print("{s}", .{self.tz});
}
pub fn format_basic(
self: Self,
writer: anytype,
) !void {
try writer.print("{s}{d:0>2}{d:0>2}", .{
self.year, @enumToInt(self.month), self.day,
});
if (self.hour) |h| {
try writer.print("T{d:0>2}", .{h});
if (self.minute) |m| {
try writer.print("{d:0>2}", .{m});
if (self.second) |s| {
try writer.print("{d:0>2}", .{s});
}
}
}
try self.tz.format_basic(writer);
}
};
test "new year" {
@ -402,3 +446,48 @@ test "ordering gt" {
try testing.expectEqual(a.compare(b), .gt);
debug.print("Passed\n", .{});
}
test "custom fmt" {
const dt = DateTime{
.year = Year.new(2023),
.month = .june,
.day = 10,
.hour = 6,
.minute = 21,
.second = 22,
.tz = .utc,
};
const dt_string = try std.fmt.allocPrint(
testing.allocator,
"{s}",
.{dt},
);
defer testing.allocator.free(dt_string);
try testing.expect(mem.eql(u8, dt_string, "2023-06-10T06:21:22Z"));
debug.print("Passed\n", .{});
}
test "fmt basic" {
const dt = DateTime{
.year = Year.new(2023),
.month = .june,
.day = 10,
.hour = 6,
.minute = 21,
.second = 22,
.tz = TimeZone.new(-4, null).?,
};
var dt_array = std.ArrayList(u8).init(testing.allocator);
defer dt_array.deinit();
var writer = dt_array.writer();
try dt.format_basic(writer);
try testing.expect(mem.eql(u8, dt_array.items, "20230610T062122-04"));
const dt_string = try std.fmt.allocPrint(
testing.allocator,
"{s}",
.{dt},
);
defer testing.allocator.free(dt_string);
try testing.expect(mem.eql(u8, dt_string, "2023-06-10T06:21:22-04"));
debug.print("Passed\n", .{});
}

View File

@ -72,4 +72,55 @@ pub const TimeZone = union(TimeZoneTag) {
}
} else if (minutes) |m| Self{ .offset = Offset.new(0, m).? } else .utc;
}
pub fn format(
self: Self,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
switch (self) {
.utc => try writer.writeAll("Z"),
.offset => |ofs| switch (ofs) {
.positive => |p| {
try writer.print("+{d:0>2}", .{p.hours});
if (p.minutes) |m| {
try writer.print(":{d:0>2}", .{m});
}
},
.negative => |n| {
try writer.print("-{d:0>2}", .{n.hours});
if (n.minutes) |m| {
try writer.print(":{d:0>2}", .{m});
}
},
},
}
}
pub fn format_basic(
self: Self,
writer: anytype,
) !void {
switch (self) {
.utc => try writer.writeAll("Z"),
.offset => |ofs| switch (ofs) {
.positive => |p| {
try writer.print("+{d:0>2}", .{p.hours});
if (p.minutes) |m| {
try writer.print("{d:0>2}", .{m});
}
},
.negative => |n| {
try writer.print("-{d:0>2}", .{n.hours});
if (n.minutes) |m| {
try writer.print("{d:0>2}", .{m});
}
},
},
}
}
};

View File

@ -50,4 +50,21 @@ pub const Year = union(YearTag) {
pub fn previous(self: Self) Self {
return Self.new(self.get() - 1);
}
pub fn format(
self: Self,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
const year = self.get();
if (year > 0) {
try writer.print("{d:0>4}", .{@intCast(u32, year)});
} else {
try writer.print("{d:0>4}", .{year});
}
}
};