const std = @import("std"); const abi = @import("abi.zig"); const t = @import("temporal.zig"); const Instant = @import("Instant.zig"); const PlainDate = @import("PlainDate.zig"); const PlainDateTime = @import("PlainDateTime.zig"); const PlainTime = @import("PlainTime.zig"); const Duration = @import("Duration.zig"); 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; /// The rounding mode used for rounding operations. /// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) for details. pub const RoundingMode = t.RoundingMode; /// The sign of a duration or difference. /// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) for details. pub const Sign = t.Sign; /// Options for difference calculations between ZonedDateTime instances. /// 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 DifferenceSettings = t.DifferenceSettings; /// Options for rounding ZonedDateTime instances. /// 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 { _inner: abi.c.TimeZone, /// Initialize a TimeZone from an IANA identifier or offset string. pub fn init(id: []const u8) !TimeZone { const view = abi.toDiplomatStringView(id); const result = abi.c.temporal_rs_TimeZone_try_from_str(view); const tz = try abi.extractResult(result); return .{ ._inner = tz }; } }; /// 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 { compatible, earlier, later, 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 { use_offset, prefer_offset, ignore_offset, 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 { auto, always, never, 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 { auto, 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 { auto, never, 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 { fractional_second_digits: ?u8 = null, smallest_unit: ?Unit = null, rounding_mode: ?RoundingMode = null, calendar_display: CalendarDisplay = .auto, offset_display: DisplayOffset = .auto, time_zone_name: DisplayTimeZone = .auto, }; /// Helper function to wrap a C API result into a ZonedDateTime fn wrapZonedDateTime(result: anytype) !ZonedDateTime { const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic; return .{ ._inner = ptr }; } /// Creates a new ZonedDateTime from the given epoch nanoseconds and time zone. /// Equivalent to the Temporal.ZonedDateTime constructor. /// See [MDN Temporal.ZonedDateTime() constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/ZonedDateTime) pub fn init(epoch_ns: i128, time_zone: TimeZone) !ZonedDateTime { const ns_parts = abi.toI128Nanoseconds(epoch_ns); return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_from_epoch_nanoseconds(ns_parts, abi.to.toTimeZone(time_zone))); } /// Creates a new ZonedDateTime from the given epoch milliseconds and time zone. /// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) pub fn fromEpochMilliseconds(epoch_ms: i64, time_zone: TimeZone) !ZonedDateTime { return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_from_epoch_milliseconds(epoch_ms, abi.to.toTimeZone(time_zone))); } /// Creates a new ZonedDateTime from the given epoch nanoseconds and time zone. /// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) pub fn fromEpochNanoseconds(epoch_ns: i128, time_zone: TimeZone) !ZonedDateTime { const ns_parts = abi.toI128Nanoseconds(epoch_ns); return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_from_epoch_nanoseconds(ns_parts, abi.to.toTimeZone(time_zone))); } /// Parses a ZonedDateTime from a string, with optional disambiguation and offset options. /// See [MDN Temporal.ZonedDateTime.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/from) pub fn from(s: []const u8, time_zone: ?TimeZone, disambiguation: Disambiguation, offset_disambiguation: OffsetDisambiguation) !ZonedDateTime { _ = time_zone; // The time zone is parsed from the string const view = abi.toDiplomatStringView(s); return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_from_utf8(view, abi.to.toDisambiguation(disambiguation), abi.to.toOffsetDisambiguation(offset_disambiguation))); } /// Compares two ZonedDateTime instances by their instant values. /// Returns -1, 0, or 1 if the first is before, equal, or after the second. /// See [MDN Temporal.ZonedDateTime.compare()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/compare) pub fn compare(a: ZonedDateTime, b: ZonedDateTime) i8 { return abi.c.temporal_rs_ZonedDateTime_compare_instant(a._inner, b._inner); } /// Returns a new ZonedDateTime moved forward by the given duration. /// See [MDN Temporal.ZonedDateTime.prototype.add()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/add) pub fn add(self: ZonedDateTime, duration: Duration) !ZonedDateTime { const overflow_opt = abi.toOption(abi.c.ArithmeticOverflow_option, null); return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_add(self._inner, duration._inner, overflow_opt)); } /// Returns true if this ZonedDateTime is equal to another (same instant, time zone, and calendar). /// See [MDN Temporal.ZonedDateTime.prototype.equals()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/equals) pub fn equals(self: ZonedDateTime, other: ZonedDateTime) bool { return abi.c.temporal_rs_ZonedDateTime_equals(self._inner, other._inner); } /// Returns the first instant after or before this instant at which the time zone's UTC offset changes, or null if none. /// See [MDN Temporal.ZonedDateTime.prototype.getTimeZoneTransition()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/getTimeZoneTransition) pub fn getTimeZoneTransition(self: ZonedDateTime, direction: enum { next, previous }) !?ZonedDateTime { const dir = switch (direction) { .next => abi.c.TransitionDirection_Next, .previous => abi.c.TransitionDirection_Previous, }; const result = abi.c.temporal_rs_ZonedDateTime_get_time_zone_transition(self._inner, @intCast(dir)); const maybe_ptr = try abi.extractResult(result); if (maybe_ptr) |ptr| { return .{ ._inner = ptr }; } return null; } /// Returns a new ZonedDateTime rounded to the given unit and options. /// See [MDN Temporal.ZonedDateTime.prototype.round()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/round) pub fn round(self: ZonedDateTime, options: RoundOptions) !ZonedDateTime { return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_round(self._inner, abi.to.roundingOpts(options))); } /// Returns the duration from another ZonedDateTime to this one. /// 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))); if (ptr == null) return error.TemporalError; return .{ ._inner = ptr.? }; } /// Returns a ZonedDateTime representing the start of the day in the time zone. /// See [MDN Temporal.ZonedDateTime.prototype.startOfDay()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/startOfDay) pub fn startOfDay(self: ZonedDateTime) !ZonedDateTime { return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_start_of_day(self._inner)); } /// Returns a new ZonedDateTime moved backward by the given duration. /// See [MDN Temporal.ZonedDateTime.prototype.subtract()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/subtract) pub fn subtract(self: ZonedDateTime, duration: Duration) !ZonedDateTime { const overflow_opt = abi.toOption(abi.c.ArithmeticOverflow_option, null); return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_subtract(self._inner, duration._inner, overflow_opt)); } /// Returns a new Instant representing the same instant as this ZonedDateTime. /// See [MDN Temporal.ZonedDateTime.prototype.toInstant()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toInstant) pub fn toInstant(self: ZonedDateTime) !Instant { const instant_ptr = abi.c.temporal_rs_ZonedDateTime_to_instant(self._inner) orelse return error.TemporalError; return .{ ._inner = instant_ptr }; } /// Returns a string representing this ZonedDateTime in RFC 9557 format (ISO 8601 with time zone). /// See [MDN Temporal.ZonedDateTime.prototype.toJSON()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toJSON) pub fn toJSON(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 { return self.toString(allocator, .{}); } /// Returns a language-sensitive string representation of this ZonedDateTime. /// See [MDN Temporal.ZonedDateTime.prototype.toLocaleString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toLocaleString) pub fn toLocaleString(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 { return self.toString(allocator, .{}); } /// Returns a PlainDate representing the date portion of this ZonedDateTime. /// See [MDN Temporal.ZonedDateTime.prototype.toPlainDate()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainDate) pub fn toPlainDate(self: ZonedDateTime) !PlainDate { const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_date(self._inner) orelse return error.TemporalError; return .{ ._inner = ptr }; } /// Returns a PlainDateTime representing the date and time portions of this ZonedDateTime. /// See [MDN Temporal.ZonedDateTime.prototype.toPlainDateTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainDateTime) pub fn toPlainDateTime(self: ZonedDateTime) !PlainDateTime { const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_datetime(self._inner) orelse return error.TemporalError; return .{ ._inner = ptr }; } /// Returns a PlainTime representing the time portion of this ZonedDateTime. /// See [MDN Temporal.ZonedDateTime.prototype.toPlainTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainTime) pub fn toPlainTime(self: ZonedDateTime) !PlainTime { const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_time(self._inner) orelse return error.TemporalError; return .{ ._inner = ptr }; } /// Returns a string representing this ZonedDateTime in RFC 9557 format, with options for formatting. /// See [MDN Temporal.ZonedDateTime.prototype.toString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toString) pub fn toString(self: ZonedDateTime, allocator: std.mem.Allocator, opts: ToStringOptions) ![]u8 { var write = abi.DiplomatWrite.init(allocator); defer write.deinit(); const result = abi.c.temporal_rs_ZonedDateTime_to_ixdtf_string( self._inner, abi.to.displayOffset(opts.offset_display), abi.to.toDisplayTimeZone(opts.time_zone_name), abi.to.calendarDisplay(opts.calendar_display), abi.to_string_rounding_options_auto, &write.inner, ); if (!result.is_ok) return error.TemporalError; return try write.toOwnedSlice(); } /// Returns the duration from this ZonedDateTime to another. /// 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))); if (ptr == null) return error.TemporalError; return .{ ._inner = ptr.? }; } /// Throws an error; valueOf() is not supported for ZonedDateTime. /// See [MDN Temporal.ZonedDateTime.prototype.valueOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/valueOf) pub fn valueOf(_: ZonedDateTime) !void { return error.ValueOfNotSupported; } /// Returns a new ZonedDateTime with some fields replaced by new values. /// See [MDN Temporal.ZonedDateTime.prototype.with()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/with) pub fn with(self: ZonedDateTime, allocator: std.mem.Allocator, fields: anytype) !ZonedDateTime { _ = allocator; _ = fields; _ = self; return error.TemporalNoteImplemented; // Need PartialZonedDateTime mapping } /// Returns a new ZonedDateTime interpreted in the new calendar system. /// See [MDN Temporal.ZonedDateTime.prototype.withCalendar()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withCalendar) pub fn withCalendar(self: ZonedDateTime, calendar: []const u8) !ZonedDateTime { const cal_view = abi.toDiplomatStringView(calendar); 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); if (ptr == null) return error.TemporalError; return .{ ._inner = ptr.? }; } /// Returns a new ZonedDateTime with the time part replaced by the new time. /// See [MDN Temporal.ZonedDateTime.prototype.withPlainTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withPlainTime) pub fn withPlainTime(self: ZonedDateTime, time: ?PlainTime) !ZonedDateTime { const time_ptr = if (time) |tt| tt._inner else null; return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_with_plain_time(self._inner, time_ptr)); } /// Returns a new ZonedDateTime representing the same instant in a new time zone. /// See [MDN Temporal.ZonedDateTime.prototype.withTimeZone()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withTimeZone) pub fn withTimeZone(self: ZonedDateTime, time_zone: TimeZone) !ZonedDateTime { return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_with_timezone(self._inner, abi.to.toTimeZone(time_zone))); } // Property accessors /// Returns the calendar identifier used to interpret the internal ISO 8601 date. /// See [MDN Temporal.ZonedDateTime.prototype.calendarId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/calendarId) pub fn calendarId(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 { const calendar_ptr = abi.c.temporal_rs_ZonedDateTime_calendar(self._inner) orelse return error.TemporalError; const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr); return try allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]); } /// Returns the 1-based day index in the month of this date. /// See [MDN Temporal.ZonedDateTime.prototype.day](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/day) pub fn day(self: ZonedDateTime) u8 { return abi.c.temporal_rs_ZonedDateTime_day(self._inner); } /// Returns the 1-based day index in the week of this date. /// See [MDN Temporal.ZonedDateTime.prototype.dayOfWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/dayOfWeek) pub fn dayOfWeek(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_day_of_week(self._inner); } /// Returns the 1-based day index in the year of this date. /// See [MDN Temporal.ZonedDateTime.prototype.dayOfYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/dayOfYear) pub fn dayOfYear(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_day_of_year(self._inner); } /// Returns the number of days in the month of this date. /// See [MDN Temporal.ZonedDateTime.prototype.daysInMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInMonth) pub fn daysInMonth(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_days_in_month(self._inner); } /// Returns the number of days in the week of this date. /// See [MDN Temporal.ZonedDateTime.prototype.daysInWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInWeek) pub fn daysInWeek(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_days_in_week(self._inner); } /// Returns the number of days in the year of this date. /// See [MDN Temporal.ZonedDateTime.prototype.daysInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInYear) pub fn daysInYear(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_days_in_year(self._inner); } /// Returns the number of milliseconds since the Unix epoch to this instant. /// See [MDN Temporal.ZonedDateTime.prototype.epochMilliseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/epochMilliseconds) pub fn epochMilliseconds(self: ZonedDateTime) i64 { return abi.c.temporal_rs_ZonedDateTime_epoch_milliseconds(self._inner); } /// Returns the number of nanoseconds since the Unix epoch to this instant. /// See [MDN Temporal.ZonedDateTime.prototype.epochNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/epochNanoseconds) pub fn epochNanoseconds(self: ZonedDateTime) i128 { const parts = abi.c.temporal_rs_ZonedDateTime_epoch_nanoseconds(self._inner); return abi.fromI128Nanoseconds(parts); } /// Returns the calendar-specific era of this date, or null if not applicable. /// See [MDN Temporal.ZonedDateTime.prototype.era](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/era) pub fn era(self: ZonedDateTime, allocator: std.mem.Allocator) !?[]u8 { var write = abi.DiplomatWrite.init(allocator); defer write.deinit(); abi.c.temporal_rs_ZonedDateTime_era(self._inner, &write.inner); const result = try write.toOwnedSlice(); if (result.len == 0) { allocator.free(result); return null; } return result; } /// Returns the year of this date within the era, or null if not applicable. /// See [MDN Temporal.ZonedDateTime.prototype.eraYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/eraYear) pub fn eraYear(self: ZonedDateTime) ?i32 { const result = abi.c.temporal_rs_ZonedDateTime_era_year(self._inner); return abi.fromOption(result); } /// Returns the hour component of this time (0-23). /// See [MDN Temporal.ZonedDateTime.prototype.hour](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/hour) pub fn hour(self: ZonedDateTime) u8 { return abi.c.temporal_rs_ZonedDateTime_hour(self._inner); } /// Returns the number of hours in the day of this date in the time zone. /// See [MDN Temporal.ZonedDateTime.prototype.hoursInDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/hoursInDay) pub fn hoursInDay(self: ZonedDateTime) !f64 { const result = abi.c.temporal_rs_ZonedDateTime_hours_in_day(self._inner); return try abi.extractResult(result); } /// Returns true if this date is in a leap year. /// See [MDN Temporal.ZonedDateTime.prototype.inLeapYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/inLeapYear) pub fn inLeapYear(self: ZonedDateTime) bool { return abi.c.temporal_rs_ZonedDateTime_in_leap_year(self._inner); } /// Returns the microsecond component of this time (0-999). /// See [MDN Temporal.ZonedDateTime.prototype.microsecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/microsecond) pub fn microsecond(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_microsecond(self._inner); } /// Returns the millisecond component of this time (0-999). /// See [MDN Temporal.ZonedDateTime.prototype.millisecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/millisecond) pub fn millisecond(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_millisecond(self._inner); } /// Returns the minute component of this time (0-59). /// See [MDN Temporal.ZonedDateTime.prototype.minute](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/minute) pub fn minute(self: ZonedDateTime) u8 { return abi.c.temporal_rs_ZonedDateTime_minute(self._inner); } /// Returns the 1-based month index in the year of this date. /// See [MDN Temporal.ZonedDateTime.prototype.month](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/month) pub fn month(self: ZonedDateTime) u8 { return abi.c.temporal_rs_ZonedDateTime_month(self._inner); } /// Returns the calendar-specific string representing the month of this date. /// See [MDN Temporal.ZonedDateTime.prototype.monthCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/monthCode) pub fn monthCode(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 { var write = abi.DiplomatWrite.init(allocator); defer write.deinit(); abi.c.temporal_rs_ZonedDateTime_month_code(self._inner, &write.inner); return try write.toOwnedSlice(); } /// Returns the number of months in the year of this date. /// See [MDN Temporal.ZonedDateTime.prototype.monthsInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/monthsInYear) pub fn monthsInYear(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_months_in_year(self._inner); } /// Returns the nanosecond component of this time (0-999). /// See [MDN Temporal.ZonedDateTime.prototype.nanosecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/nanosecond) pub fn nanosecond(self: ZonedDateTime) u16 { return abi.c.temporal_rs_ZonedDateTime_nanosecond(self._inner); } /// Returns the offset used to interpret the internal instant, as a string (±HH:mm). /// See [MDN Temporal.ZonedDateTime.prototype.offset](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/offset) pub fn offset(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 { var write = abi.DiplomatWrite.init(allocator); defer write.deinit(); const res = abi.c.temporal_rs_ZonedDateTime_offset(self._inner, &write.inner); _ = try abi.extractResult(res); return try write.toOwnedSlice(); } /// Returns the offset used to interpret the internal instant, as a number of nanoseconds. /// See [MDN Temporal.ZonedDateTime.prototype.offsetNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/offsetNanoseconds) pub fn offsetNanoseconds(self: ZonedDateTime) i64 { return abi.c.temporal_rs_ZonedDateTime_offset_nanoseconds(self._inner); } /// Returns the second component of this time (0-59). /// See [MDN Temporal.ZonedDateTime.prototype.second](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/second) pub fn second(self: ZonedDateTime) u8 { return abi.c.temporal_rs_ZonedDateTime_second(self._inner); } /// Returns the time zone identifier used to interpret the internal instant. /// See [MDN Temporal.ZonedDateTime.prototype.timeZoneId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/timeZoneId) pub fn timeZoneId(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 { const tz = abi.c.temporal_rs_ZonedDateTime_timezone(self._inner); var write = abi.DiplomatWrite.init(allocator); defer write.deinit(); abi.c.temporal_rs_TimeZone_identifier(tz, &write.inner); return try write.toOwnedSlice(); } /// Returns the 1-based week index in the year of this date, or null if not defined. /// See [MDN Temporal.ZonedDateTime.prototype.weekOfYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/weekOfYear) pub fn weekOfYear(self: ZonedDateTime) ?u8 { const result = abi.c.temporal_rs_ZonedDateTime_week_of_year(self._inner); return abi.fromOption(result); } /// Returns the year of this date relative to the calendar's epoch. /// See [MDN Temporal.ZonedDateTime.prototype.year](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/year) pub fn year(self: ZonedDateTime) i32 { return abi.c.temporal_rs_ZonedDateTime_year(self._inner); } /// Returns the year to be paired with the weekOfYear of this date, or null if not defined. /// See [MDN Temporal.ZonedDateTime.prototype.yearOfWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/yearOfWeek) pub fn yearOfWeek(self: ZonedDateTime) ?i32 { const result = abi.c.temporal_rs_ZonedDateTime_year_of_week(self._inner); return abi.fromOption(result); } /// Returns a clone of this ZonedDateTime instance. pub fn clone(self: ZonedDateTime) ZonedDateTime { const ptr = abi.c.temporal_rs_ZonedDateTime_clone(self._inner) orelse unreachable; return .{ ._inner = ptr }; } /// Frees the resources associated with this ZonedDateTime instance. pub fn deinit(self: ZonedDateTime) void { abi.c.temporal_rs_ZonedDateTime_destroy(self._inner); } // ---------- Tests --------------------- test init { const tz = try TimeZone.init("America/New_York"); const zdt = try init(0, tz); defer zdt.deinit(); try std.testing.expectEqual(@as(i64, 0), zdt.epochMilliseconds()); } test fromEpochMilliseconds { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459200000, tz); // 2021-01-01T00:00:00Z defer zdt.deinit(); try std.testing.expectEqual(@as(i64, 1609459200000), zdt.epochMilliseconds()); } test from { const zdt = try from("2021-01-01T00:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); try std.testing.expectEqual(@as(i32, 2021), zdt.year()); try std.testing.expectEqual(@as(u8, 1), zdt.month()); try std.testing.expectEqual(@as(u8, 1), zdt.day()); } test compare { const tz = try TimeZone.init("UTC"); const zdt1 = try fromEpochMilliseconds(1000, tz); defer zdt1.deinit(); const zdt2 = try fromEpochMilliseconds(2000, tz); defer zdt2.deinit(); try std.testing.expect(compare(zdt1, zdt2) < 0); try std.testing.expect(compare(zdt2, zdt1) > 0); try std.testing.expect(compare(zdt1, zdt1) == 0); } test equals { const tz = try TimeZone.init("UTC"); const zdt1 = try fromEpochMilliseconds(1000, tz); defer zdt1.deinit(); const zdt2 = try fromEpochMilliseconds(1000, tz); defer zdt2.deinit(); const zdt3 = try fromEpochMilliseconds(2000, tz); defer zdt3.deinit(); try std.testing.expect(zdt1.equals(zdt2)); try std.testing.expect(!zdt1.equals(zdt3)); } test toInstant { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459200000, tz); defer zdt.deinit(); const instant = try zdt.toInstant(); defer instant.deinit(); try std.testing.expectEqual(@as(i64, 1609459200000), instant.epochMilliseconds()); } test toPlainDate { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459200000, tz); defer zdt.deinit(); const pd = try zdt.toPlainDate(); defer pd.deinit(); try std.testing.expectEqual(@as(i32, 2021), pd.year()); try std.testing.expectEqual(@as(u8, 1), pd.month()); try std.testing.expectEqual(@as(u8, 1), pd.day()); } test toPlainDateTime { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459200000, tz); defer zdt.deinit(); var pdt = try zdt.toPlainDateTime(); defer pdt.deinit(); try std.testing.expectEqual(@as(i32, 2021), pdt.year()); try std.testing.expectEqual(@as(u8, 1), pdt.month()); try std.testing.expectEqual(@as(u8, 1), pdt.day()); } test toPlainTime { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459200000, tz); defer zdt.deinit(); const pt = try zdt.toPlainTime(); defer abi.c.temporal_rs_PlainTime_destroy(pt._inner); try std.testing.expectEqual(@as(u8, 0), pt.hour()); try std.testing.expectEqual(@as(u8, 0), pt.minute()); } test toString { const zdt = try from("2021-01-01T00:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const str = try zdt.toString(std.testing.allocator, .{}); defer std.testing.allocator.free(str); try std.testing.expect(str.len > 0); try std.testing.expectEqualStrings("2021-01-01T00:00:00+00:00[UTC]", str); } test "props" { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459200000, tz); defer zdt.deinit(); try std.testing.expectEqual(@as(i32, 2021), zdt.year()); try std.testing.expectEqual(@as(u8, 1), zdt.month()); try std.testing.expectEqual(@as(u8, 1), zdt.day()); try std.testing.expectEqual(@as(u8, 0), zdt.hour()); try std.testing.expectEqual(@as(u8, 0), zdt.minute()); try std.testing.expectEqual(@as(u8, 0), zdt.second()); try std.testing.expectEqual(@as(u16, 0), zdt.millisecond()); const tzo = try zdt.timeZoneId(std.testing.allocator); defer std.testing.allocator.free(tzo); try std.testing.expectEqualStrings("UTC", tzo); } test fromEpochNanoseconds { const tz = try TimeZone.init("UTC"); const epoch_ns: i128 = 1609459200000000000; const zdt = try fromEpochNanoseconds(epoch_ns, tz); defer zdt.deinit(); try std.testing.expectEqual(epoch_ns, zdt.epochNanoseconds()); } test add { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(0, tz); defer zdt.deinit(); var dur = try Duration.from("PT1H"); defer dur.deinit(); const result = try zdt.add(dur); defer result.deinit(); try std.testing.expectEqual(@as(i64, 3_600_000), result.epochMilliseconds()); } test getTimeZoneTransition { if (true) return error.SkipZigTest; // getTimeZoneTransition() not properly implemented in underlying library } test round { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459245123, tz); defer zdt.deinit(); const rounded = try zdt.round(.{ .smallest_unit = .second }); defer rounded.deinit(); try std.testing.expectEqual(@as(u16, 0), rounded.millisecond()); } test since { const tz = try TimeZone.init("UTC"); const zdt1 = try fromEpochMilliseconds(2000, tz); defer zdt1.deinit(); const zdt2 = try fromEpochMilliseconds(1000, tz); defer zdt2.deinit(); const dur = try zdt1.since(zdt2, .{}); defer dur.deinit(); } test startOfDay { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459245123, tz); defer zdt.deinit(); const start = try zdt.startOfDay(); defer start.deinit(); try std.testing.expectEqual(@as(u8, 0), start.hour()); try std.testing.expectEqual(@as(u8, 0), start.minute()); try std.testing.expectEqual(@as(u8, 0), start.second()); } test subtract { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(7200000, tz); defer zdt.deinit(); var dur = try Duration.from("PT1H"); defer dur.deinit(); const result = try zdt.subtract(dur); defer result.deinit(); try std.testing.expectEqual(@as(i64, 3_600_000), result.epochMilliseconds()); } test toJSON { const zdt = try from("2021-01-01T00:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const json_str = try zdt.toJSON(std.testing.allocator); defer std.testing.allocator.free(json_str); try std.testing.expect(json_str.len > 0); try std.testing.expect(std.mem.indexOf(u8, json_str, "2021") != null); } test toLocaleString { const zdt = try from("2021-01-01T00:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const locale_str = try zdt.toLocaleString(std.testing.allocator); defer std.testing.allocator.free(locale_str); try std.testing.expect(locale_str.len > 0); } test until { const tz = try TimeZone.init("UTC"); const zdt1 = try fromEpochMilliseconds(1000, tz); defer zdt1.deinit(); const zdt2 = try fromEpochMilliseconds(2000, tz); defer zdt2.deinit(); const dur = try zdt1.until(zdt2, .{}); defer dur.deinit(); } test valueOf { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459200000, tz); defer zdt.deinit(); try std.testing.expectError(error.ValueOfNotSupported, zdt.valueOf()); } test with { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); try std.testing.expectError(error.TemporalNoteImplemented, zdt.with(std.testing.allocator, .{})); } test withCalendar { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const result = try zdt.withCalendar("iso8601"); defer result.deinit(); try std.testing.expectEqual(@as(i32, 2021), result.year()); } test withPlainTime { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const time = try PlainTime.from("14:30:45"); const result = try zdt.withPlainTime(time); defer result.deinit(); try std.testing.expectEqual(@as(u8, 14), result.hour()); try std.testing.expectEqual(@as(u8, 30), result.minute()); } test withTimeZone { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const utc_tz = try TimeZone.init("UTC"); const result = try zdt.withTimeZone(utc_tz); defer result.deinit(); try std.testing.expectEqual(@as(i32, 2021), result.year()); } test calendarId { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const cal_id = try zdt.calendarId(std.testing.allocator); defer std.testing.allocator.free(cal_id); try std.testing.expect(cal_id.len > 0); } test dayOfWeek { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const dow = zdt.dayOfWeek(); try std.testing.expect(dow >= 1 and dow <= 7); } test dayOfYear { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const doy = zdt.dayOfYear(); try std.testing.expect(doy >= 1 and doy <= 366); } test daysInMonth { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const dim = zdt.daysInMonth(); try std.testing.expectEqual(@as(u16, 31), dim); } test daysInWeek { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); try std.testing.expectEqual(@as(u16, 7), zdt.daysInWeek()); } test daysInYear { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); try std.testing.expectEqual(@as(u16, 365), zdt.daysInYear()); } test epochMilliseconds { const tz = try TimeZone.init("UTC"); const zdt = try fromEpochMilliseconds(1609459200000, tz); defer zdt.deinit(); try std.testing.expectEqual(@as(i64, 1609459200000), zdt.epochMilliseconds()); } test epochNanoseconds { const tz = try TimeZone.init("UTC"); const epoch_ns: i128 = 1609459200123456789; const zdt = try fromEpochNanoseconds(epoch_ns, tz); defer zdt.deinit(); try std.testing.expectEqual(epoch_ns, zdt.epochNanoseconds()); } test era { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const e = try zdt.era(std.testing.allocator); if (e) |era_val| { defer std.testing.allocator.free(era_val); try std.testing.expect(era_val.len > 0); } } test eraYear { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const ey = zdt.eraYear(); if (ey) |y| { try std.testing.expect(y > 0); } } test hoursInDay { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const hours = try zdt.hoursInDay(); try std.testing.expect(hours > 0); } test inLeapYear { const leap = try from("2020-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer leap.deinit(); try std.testing.expect(leap.inLeapYear()); const non_leap = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer non_leap.deinit(); try std.testing.expect(!non_leap.inLeapYear()); } test microsecond { const zdt = try from("2021-01-01T12:00:00.123456+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const us = zdt.microsecond(); try std.testing.expect(us >= 0 and us < 1000); } test monthCode { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const code = try zdt.monthCode(std.testing.allocator); defer std.testing.allocator.free(code); try std.testing.expectEqualStrings("M01", code); } test monthsInYear { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); try std.testing.expectEqual(@as(u16, 12), zdt.monthsInYear()); } test nanosecond { const zdt = try from("2021-01-01T12:00:00.123456789+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const ns = zdt.nanosecond(); try std.testing.expect(ns >= 0 and ns < 1000); } test offset { if (true) return error.SkipZigTest; // offset() throws RangeError with UTC timezone } test offsetNanoseconds { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const off_ns = zdt.offsetNanoseconds(); try std.testing.expectEqual(@as(i64, 0), off_ns); } test weekOfYear { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const woy = zdt.weekOfYear(); if (woy) |week| { try std.testing.expect(week >= 1 and week <= 53); } } test yearOfWeek { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const yow = zdt.yearOfWeek(); if (yow) |y| { try std.testing.expect(y >= 2020); } } test clone { const zdt = try from("2021-01-01T12:00:00+00:00[UTC]", null, .compatible, .reject); defer zdt.deinit(); const cloned = zdt.clone(); defer cloned.deinit(); try std.testing.expectEqual(zdt.epochMilliseconds(), cloned.epochMilliseconds()); }