From da8534cd19090dde64fa8b47210b0c659fd2674f Mon Sep 17 00:00:00 2001 From: "Nurul Huda (Apon)" Date: Mon, 2 Feb 2026 12:51:10 +0600 Subject: [PATCH] chore: extend example with more methods --- example/src/main.zig | 346 ++++++++++++++++++++++++++++++++++++++++-- src/Duration.zig | 5 +- src/ZonedDateTime.zig | 19 +-- 3 files changed, 347 insertions(+), 23 deletions(-) diff --git a/example/src/main.zig b/example/src/main.zig index 5c7c8dc..834b7ae 100644 --- a/example/src/main.zig +++ b/example/src/main.zig @@ -14,10 +14,14 @@ pub fn main() !void { \\ - toString(): {s} \\ \\ - , .{ instant.epochMilliseconds(), instant.epochNanoseconds(), try instant.toString(allocator, .{}) }); + , .{ + instant.epochMilliseconds(), + instant.epochNanoseconds(), + try instant.toString(allocator, .{}), + }); // --- Duration --- // - const dur = try Temporal.Duration.from("P1Y2M3DT4H5M6S"); + const dur = try Temporal.Duration.from("PT1H"); defer dur.deinit(); std.debug.print( \\Duration @@ -33,7 +37,18 @@ pub fn main() !void { \\ - toString(): {s} \\ \\ - , .{ dur.nanoseconds(), dur.milliseconds(), dur.seconds(), dur.minutes(), dur.hours(), dur.days(), dur.weeks(), dur.months(), dur.years(), try dur.toString(allocator, .{}) }); + , .{ + dur.nanoseconds(), + dur.milliseconds(), + dur.seconds(), + dur.minutes(), + dur.hours(), + dur.days(), + dur.weeks(), + dur.months(), + dur.years(), + try dur.toString(allocator, .{}), + }); // --- Now --- // const now_instant = try Temporal.Now.instant(); @@ -50,7 +65,12 @@ pub fn main() !void { \\ - time: {s} \\ \\ - , .{ try now_instant.toString(allocator, .{}), try now_date.toString(allocator, .{}), try now_datetime.toString(allocator, .{}), try now_time.toString(allocator) }); + , .{ + try now_instant.toString(allocator, .{}), + try now_date.toString(allocator, .{}), + try now_datetime.toString(allocator, .{}), + try now_time.toString(allocator), + }); // --- PlainDate --- // const date = try Temporal.PlainDate.init(2024, 2, 2); @@ -63,7 +83,12 @@ pub fn main() !void { \\ - toString(): {s} \\ \\ - , .{ date.year(), date.month(), date.day(), try date.toString(allocator, .{}) }); + , .{ + date.year(), + date.month(), + date.day(), + try date.toString(allocator, .{}), + }); // --- PlainDateTime --- // const dt = try Temporal.PlainDateTime.init(2024, 2, 2, 13, 45, 30, 123, 456, 789); @@ -78,7 +103,15 @@ pub fn main() !void { \\ - toString(): {s} \\ \\ - , .{ dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute(), dt.second(), try dt.toString(allocator, .{}) }); + , .{ + dt.year(), + dt.month(), + dt.day(), + dt.hour(), + dt.minute(), + dt.second(), + try dt.toString(allocator, .{}), + }); // --- PlainMonthDay --- // const md = try Temporal.PlainMonthDay.init(2, 2, null); @@ -89,7 +122,11 @@ pub fn main() !void { \\ - toString(): {s} \\ \\ - , .{ try md.monthCode(allocator), md.day(), try md.toString(allocator) }); + , .{ + try md.monthCode(allocator), + md.day(), + try md.toString(allocator), + }); // --- PlainTime --- // const tm = try Temporal.PlainTime.init(13, 45, 30, 123, 456, 789); @@ -101,7 +138,12 @@ pub fn main() !void { \\ - toString(): {s} \\ \\ - , .{ tm.hour(), tm.minute(), tm.second(), try tm.toString(allocator) }); + , .{ + tm.hour(), + tm.minute(), + tm.second(), + try tm.toString(allocator), + }); // --- PlainYearMonth --- // const ym = try Temporal.PlainYearMonth.init(2024, 2, null); @@ -132,5 +174,291 @@ pub fn main() !void { \\ - toString(): {s} \\ \\ - , .{ zdt.year(), zdt.month(), zdt.day(), zdt.hour(), zdt.minute(), zdt.second(), try zdt.timeZoneId(allocator), try zdt.toString(allocator, .{}) }); + , .{ + zdt.year(), + zdt.month(), + zdt.day(), + zdt.hour(), + zdt.minute(), + zdt.second(), + try zdt.timeZoneId(allocator), + try zdt.toString(allocator, .{}), + }); + + // ---- + // More complex Temporal API examples + // ---- + + // Duration arithmetic + const dur1 = try Temporal.Duration.from("P1DT2H"); + const dur2 = try Temporal.Duration.from("PT30M"); + const dur_sum = try dur1.add(dur2); + std.debug.print( + \\Duration Arithmetic + \\ - dur1: {s} + \\ - dur2: {s} + \\ - dur1 + dur2: {s} + \\ + \\ + , .{ + try dur1.toString(allocator, .{}), + try dur2.toString(allocator, .{}), + try dur_sum.toString(allocator, .{}), + }); + + // Instant comparison and arithmetic + const inst1 = try Temporal.Instant.init(1_704_067_200_000_000_000); + const inst2 = try Temporal.Instant.init(1_704_153_600_000_000_000); // +1 day + const inst_diff = try inst2.since(inst1, Temporal.Instant.DifferenceSettings{}); + std.debug.print( + \\Instant Comparison + \\ - inst1: {s} + \\ - inst2: {s} + \\ - inst2.since(inst1): {s} + \\ + \\ + , .{ + try inst1.toString(allocator, .{}), + try inst2.toString(allocator, .{}), + try inst_diff.toString(allocator, .{}), + }); + + // PlainDate to PlainDateTime and back + const pd = try Temporal.PlainDate.init(2024, 2, 2); + const pdt = try pd.toPlainDateTime(try Temporal.PlainTime.init(12, 0, 0, 0, 0, 0)); + std.debug.print( + \\PlainDate/PlainDateTime Conversion + \\ - PlainDate: {s} + \\ - toPlainDateTime(12:00): {s} + \\ - toPlainDate(): {s} + \\ + \\ + , .{ + try pd.toString(allocator, .{}), + try pdt.toString(allocator, .{}), + try (try pdt.toPlainDate()).toString(allocator, .{}), + }); + + // ZonedDateTime to Instant and back + const zdt2 = try Temporal.ZonedDateTime.fromEpochNanoseconds(1706881530123456789, tz); + const zdt2_inst = try zdt2.toInstant(); + const zdt2_from_inst = try Temporal.ZonedDateTime.fromEpochNanoseconds(zdt2_inst.epochNanoseconds(), tz); + std.debug.print( + \\ZonedDateTime/Instant Conversion + \\ - ZonedDateTime: {s} + \\ - toInstant(): {s} + \\ - fromEpochNanoseconds(instant): {s} + \\ + \\ + , .{ + try zdt2.toString(allocator, .{}), + try zdt2_inst.toString(allocator, .{}), + try zdt2_from_inst.toString(allocator, .{}), + }); + + // ---- + // Further more complex examples covering more methods + // ---- + + // Duration: abs, negated, round, subtract, total, valueOf + const dur_neg = dur.negated(); + const dur_abs = dur_neg.abs(); + const dur_sub = try dur.subtract(dur2); + const dur_rounded = try dur.round(.{ .smallest_unit = Temporal.Duration.Unit.hour }); + const dur_total_hours = try dur.total(.{ .unit = Temporal.Duration.Unit.hour }); + std.debug.print( + \\Duration Advanced + \\ - negated: {s} + \\ - abs: {s} + \\ - subtract dur2: {s} + \\ - round to hour: {s} + \\ - total hours: {d} + \\ + \\ + , .{ + try dur_neg.toString(allocator, .{}), + try dur_abs.toString(allocator, .{}), + try dur_sub.toString(allocator, .{}), + try dur_rounded.toString(allocator, .{}), + dur_total_hours, + }); + + // Instant: add, subtract, round, equals, valueOf + const inst_add = try inst1.add(@constCast(&dur)); + const inst_sub = try inst2.subtract(@constCast(&dur)); + const inst_rounded = try inst1.round(.{ .smallest_unit = Temporal.Instant.Unit.second }); + const inst_eq = Temporal.Instant.compare(inst1, inst1) == 0; + std.debug.print( + \\Instant Advanced + \\ - add duration: {s} + \\ - subtract duration: {s} + \\ - round to second: {s} + \\ - inst1 equals inst1: {} + \\ + \\ + , .{ + try inst_add.toString(allocator, .{}), + try inst_sub.toString(allocator, .{}), + try inst_rounded.toString(allocator, .{}), + inst_eq, + }); + + // PlainDate: add, subtract, with, equals, since, until, withCalendar + const date_added = try date.add(dur); + const date_sub = try date.subtract(dur); + // const date_with = try date.with(.{ .year = 2025 }); + const date_eq = date.equals(date); + const date_since = try date.since(date, Temporal.PlainDate.DifferenceSettings{}); + const date_until = try date.until(date, Temporal.PlainDate.DifferenceSettings{}); + const date_with_cal = try date.withCalendar("iso8601"); + std.debug.print( + \\PlainDate Advanced + \\ - equals self: {} + \\ - add duration: {s} + \\ - subtract duration: {s} + \\ - since self: {s} + \\ - until self: {s} + \\ - withCalendar: {s} + \\ - with year=2025: {{s}} + \\ + \\ + , + .{ + date_eq, + try date_added.toString(allocator, .{}), + try date_sub.toString(allocator, .{}), + try date_since.toString(allocator, .{}), + try date_until.toString(allocator, .{}), + try date_with_cal.toString(allocator, .{}), + // try date_with.toString(allocator, .{}), + }, + ); + + // PlainDateTime: add, subtract, round, with, equals, since, until, withCalendar, withPlainTime + const dt_added = try dt.add(dur); + const dt_sub = try dt.subtract(dur); + const dt_rounded = try dt.round(.{ .smallest_unit = Temporal.PlainDateTime.Unit.minute }); + const dt_with = try dt.with(.{ .year = 2025 }); + const dt_eq = dt.equals(dt); + const dt_since = try dt.since(dt, Temporal.PlainDateTime.DifferenceSettings{}); + const dt_until = try dt.until(dt, Temporal.PlainDateTime.DifferenceSettings{}); + const dt_with_cal = try dt.withCalendar("iso8601"); + const dt_with_time = try dt.withPlainTime(try Temporal.PlainTime.init(1, 2, 3, 4, 5, 6)); + std.debug.print( + \\PlainDateTime Advanced + \\ - add duration: {s} + \\ - subtract duration: {s} + \\ - round to minute: {s} + \\ - with year=2025: {s} + \\ - equals self: {} + \\ - since self: {s} + \\ - until self: {s} + \\ - withCalendar: {s} + \\ - withPlainTime: {s} + \\ + \\ + , .{ + try dt_added.toString(allocator, .{}), + try dt_sub.toString(allocator, .{}), + try dt_rounded.toString(allocator, .{}), + try dt_with.toString(allocator, .{}), + dt_eq, + try dt_since.toString(allocator, .{}), + try dt_until.toString(allocator, .{}), + try dt_with_cal.toString(allocator, .{}), + try dt_with_time.toString(allocator, .{}), + }); + + // PlainTime: add, subtract, round, with, equals, since, until + const tm_added = try tm.add(dur); + const tm_sub = try tm.subtract(dur); + const tm_rounded = try tm.round(.{ .smallest_unit = Temporal.PlainTime.Unit.second }); + const tm_with = try tm.with(.{ .hour = 1 }); + const tm_eq = tm.equals(tm); + const tm_since = try tm.since(tm, Temporal.PlainTime.DifferenceSettings{}); + const tm_until = try tm.until(tm, Temporal.PlainTime.DifferenceSettings{}); + std.debug.print( + \\PlainTime Advanced + \\ - add duration: {s} + \\ - subtract duration: {s} + \\ - round to second: {s} + \\ - with hour=1: {s} + \\ - equals self: {} + \\ - since self: {s} + \\ - until self: {s} + \\ + \\ + , .{ + try tm_added.toString(allocator), + try tm_sub.toString(allocator), + try tm_rounded.toString(allocator), + try tm_with.toString(allocator), + tm_eq, + try tm_since.toString(allocator, .{}), + try tm_until.toString(allocator, .{}), + }); + + // PlainYearMonth: add, subtract, with, equals, since, until, withCalendar + const ym_added = try ym.add(dur); + const ym_sub = try ym.subtract(dur); + const ym_with = try ym.with(.{ .year = 2025 }); + const ym_eq = ym.equals(ym); + const ym_since = try ym.since(ym, Temporal.PlainYearMonth.DifferenceSettings{}); + const ym_until = try ym.until(ym, Temporal.PlainYearMonth.DifferenceSettings{}); + std.debug.print( + \\PlainYearMonth Advanced + \\ - add duration: {s} + \\ - subtract duration: {s} + \\ - with year=2025: {s} + \\ - equals self: {} + \\ - since self: {s} + \\ - until self: {s} + \\ + \\ + , .{ + try ym_added.toString(allocator), + try ym_sub.toString(allocator), + try ym_with.toString(allocator), + ym_eq, + try ym_since.toString(allocator, .{}), + try ym_until.toString(allocator, .{}), + }); + + // ZonedDateTime: add, subtract, round, with, equals, since, until, withCalendar, withPlainTime, withTimeZone + const zdt_added = try zdt.add(dur); + const zdt_sub = try zdt.subtract(dur); + const zdt_rounded = try zdt.round(.{ .smallest_unit = Temporal.ZonedDateTime.Unit.hour }); + // const zdt_with = try zdt.with(allocator, .{ .year = 2025 }); + const zdt_eq = zdt.equals(zdt); + const zdt_since = try zdt.since(zdt, Temporal.ZonedDateTime.DifferenceSettings{}); + const zdt_until = try zdt.until(zdt, Temporal.ZonedDateTime.DifferenceSettings{}); + const zdt_with_cal = try zdt.withCalendar("iso8601"); + const zdt_with_time = try zdt.withPlainTime(try Temporal.PlainTime.init(1, 2, 3, 4, 5, 6)); + const zdt_with_tz = try zdt.withTimeZone(tz); + std.debug.print( + \\ZonedDateTime Advanced + \\ - add duration: {s} + \\ - subtract duration: {s} + \\ - round to hour: {s} + \\ - with year=2025: {{s}} + \\ - equals self: {} + \\ - since self: {s} + \\ - until self: {s} + \\ - withCalendar: {s} + \\ - withPlainTime: {s} + \\ - withTimeZone: {s} + \\ + \\ + , .{ + try zdt_added.toString(allocator, .{}), + try zdt_sub.toString(allocator, .{}), + try zdt_rounded.toString(allocator, .{}), + // try zdt_with.toString(allocator, .{}), + zdt_eq, + try zdt_since.toString(allocator, .{}), + try zdt_until.toString(allocator, .{}), + try zdt_with_cal.toString(allocator, .{}), + try zdt_with_time.toString(allocator, .{}), + try zdt_with_tz.toString(allocator, .{}), + }); } diff --git a/src/Duration.zig b/src/Duration.zig index 82a1d7d..3d19fa2 100644 --- a/src/Duration.zig +++ b/src/Duration.zig @@ -346,8 +346,9 @@ inline fn handleVoidResult(res: anytype) !void { } fn wrapDuration(res: anytype) !Duration { - const ptr = (try abi.extractResult(res)) orelse return abi.TemporalError.Generic; - return .{ ._inner = ptr }; + const ptr = try abi.extractResult(res); + if (ptr == null) return abi.TemporalError.RangeError; + return .{ ._inner = ptr.? }; } // --- Aliases and enums ------------------------------------------ diff --git a/src/ZonedDateTime.zig b/src/ZonedDateTime.zig index ce9a101..4bf9780 100644 --- a/src/ZonedDateTime.zig +++ b/src/ZonedDateTime.zig @@ -12,7 +12,6 @@ const ZonedDateTime = @This(); _inner: *abi.c.ZonedDateTime, - /// The unit of time used for rounding and difference calculations. /// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) for details. pub const Unit = t.Unit; @@ -33,7 +32,6 @@ pub const DifferenceSettings = t.DifferenceSettings; /// See [MDN Temporal.ZonedDateTime#instance_methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#instance_methods) for details. pub const RoundOptions = t.RoundingOptions; - /// Represents a time zone, identified by an IANA time zone identifier or a fixed offset. /// See [MDN Temporal.ZonedDateTime#time-zones-and-offsets](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#time-zones-and-offsets). pub const TimeZone = struct { @@ -48,7 +46,6 @@ pub const TimeZone = struct { } }; - /// Disambiguation options for resolving ambiguous local times (e.g., during DST transitions). /// See [MDN Temporal.ZonedDateTime#ambiguity-and-gaps-from-local-time-to-utc-time](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#ambiguity-and-gaps-from-local-time-to-utc-time). pub const Disambiguation = enum { @@ -58,7 +55,6 @@ pub const Disambiguation = enum { reject, }; - /// Options for resolving offset ambiguity when parsing ZonedDateTime from a string. /// See [MDN Temporal.ZonedDateTime#offset-ambiguity](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#offset-ambiguity). pub const OffsetDisambiguation = enum { @@ -68,7 +64,6 @@ pub const OffsetDisambiguation = enum { reject, }; - /// Controls how the calendar is displayed in string output. /// See [MDN Temporal.ZonedDateTime#rfc-9557-format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#rfc-9557-format). pub const CalendarDisplay = enum { @@ -78,7 +73,6 @@ pub const CalendarDisplay = enum { critical, }; - /// Controls how the offset is displayed in string output. /// See [MDN Temporal.ZonedDateTime#rfc-9557-format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#rfc-9557-format). pub const DisplayOffset = enum { @@ -86,7 +80,6 @@ pub const DisplayOffset = enum { never, }; - /// Controls how the time zone is displayed in string output. /// See [MDN Temporal.ZonedDateTime#rfc-9557-format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#rfc-9557-format). pub const DisplayTimeZone = enum { @@ -95,7 +88,6 @@ pub const DisplayTimeZone = enum { critical, }; - /// Options for formatting ZonedDateTime as a string. /// See [MDN Temporal.ZonedDateTime#rfc-9557-format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#rfc-9557-format). pub const ToStringOptions = struct { @@ -187,7 +179,8 @@ pub fn round(self: ZonedDateTime, options: RoundOptions) !ZonedDateTime { /// See [MDN Temporal.ZonedDateTime.prototype.since()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/since) pub fn since(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSettings) !Duration { const ptr = try abi.extractResult(abi.c.temporal_rs_ZonedDateTime_since(self._inner, other._inner, abi.to.diffsettings(settings))); - return .{ ._inner = ptr }; + if (ptr == null) return error.TemporalError; + return .{ ._inner = ptr.? }; } /// Returns a ZonedDateTime representing the start of the day in the time zone. @@ -266,7 +259,8 @@ pub fn toString(self: ZonedDateTime, allocator: std.mem.Allocator, opts: ToStrin /// See [MDN Temporal.ZonedDateTime.prototype.until()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/until) pub fn until(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSettings) !Duration { const ptr = try abi.extractResult(abi.c.temporal_rs_ZonedDateTime_until(self._inner, other._inner, abi.to.diffsettings(settings))); - return .{ ._inner = ptr }; + if (ptr == null) return error.TemporalError; + return .{ ._inner = ptr.? }; } /// Throws an error; valueOf() is not supported for ZonedDateTime. @@ -281,7 +275,7 @@ pub fn with(self: ZonedDateTime, allocator: std.mem.Allocator, fields: anytype) _ = allocator; _ = fields; _ = self; - return error.Todo; // Need PartialZonedDateTime mapping + return error.TemporalNoteImplemented; // Need PartialZonedDateTime mapping } /// Returns a new ZonedDateTime interpreted in the new calendar system. @@ -291,7 +285,8 @@ pub fn withCalendar(self: ZonedDateTime, calendar: []const u8) !ZonedDateTime { const cal_result = abi.c.temporal_rs_AnyCalendarKind_parse_temporal_calendar_string(cal_view); const cal_kind = try abi.extractResult(cal_result); const ptr = abi.c.temporal_rs_ZonedDateTime_with_calendar(self._inner, cal_kind); - return .{ ._inner = ptr, .calendar_id = calendar }; + if (ptr == null) return error.TemporalError; + return .{ ._inner = ptr.? }; } /// Returns a new ZonedDateTime with the time part replaced by the new time.