2021-07-11 21:04:11 +03:00
/*
* Copyright ( c ) 2021 , Idan Horowitz < idan . horowitz @ serenityos . org >
2023-01-26 14:07:33 +00:00
* Copyright ( c ) 2021 - 2023 , Linus Groh < linusg @ serenityos . org >
2021-07-11 21:04:11 +03:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2022-11-23 13:41:50 +01:00
# include <AK/TypeCasts.h>
2021-07-22 19:47:07 +01:00
# include <LibJS/Runtime/AbstractOperations.h>
2021-09-17 21:03:49 +02:00
# include <LibJS/Runtime/Completion.h>
2021-07-11 21:04:11 +03:00
# include <LibJS/Runtime/Date.h>
# include <LibJS/Runtime/GlobalObject.h>
2021-08-22 23:16:42 +01:00
# include <LibJS/Runtime/Temporal/AbstractOperations.h>
# include <LibJS/Runtime/Temporal/Calendar.h>
2021-11-01 14:20:06 +01:00
# include <LibJS/Runtime/Temporal/Duration.h>
2021-08-22 23:16:42 +01:00
# include <LibJS/Runtime/Temporal/Instant.h>
2021-07-11 21:04:11 +03:00
# include <LibJS/Runtime/Temporal/PlainDate.h>
# include <LibJS/Runtime/Temporal/PlainDateTime.h>
2021-07-22 19:47:07 +01:00
# include <LibJS/Runtime/Temporal/PlainDateTimeConstructor.h>
2021-07-11 21:04:11 +03:00
# include <LibJS/Runtime/Temporal/PlainTime.h>
2021-08-22 23:16:42 +01:00
# include <LibJS/Runtime/Temporal/TimeZone.h>
# include <LibJS/Runtime/Temporal/ZonedDateTime.h>
2021-07-11 21:04:11 +03:00
namespace JS : : Temporal {
2021-07-22 19:47:07 +01:00
// 5 Temporal.PlainDateTime Objects, https://tc39.es/proposal-temporal/#sec-temporal-plaindatetime-objects
2021-07-28 18:31:32 +01:00
PlainDateTime : : PlainDateTime ( i32 iso_year , u8 iso_month , u8 iso_day , u8 iso_hour , u8 iso_minute , u8 iso_second , u16 iso_millisecond , u16 iso_microsecond , u16 iso_nanosecond , Object & calendar , Object & prototype )
2022-12-14 12:17:58 +01:00
: Object ( ConstructWithPrototypeTag : : Tag , prototype )
2021-07-22 19:47:07 +01:00
, m_iso_year ( iso_year )
, m_iso_month ( iso_month )
, m_iso_day ( iso_day )
, m_iso_hour ( iso_hour )
, m_iso_minute ( iso_minute )
, m_iso_second ( iso_second )
, m_iso_millisecond ( iso_millisecond )
, m_iso_microsecond ( iso_microsecond )
, m_iso_nanosecond ( iso_nanosecond )
, m_calendar ( calendar )
{
}
void PlainDateTime : : visit_edges ( Visitor & visitor )
{
2021-08-14 20:09:26 +02:00
Base : : visit_edges ( visitor ) ;
2021-07-22 19:47:07 +01:00
visitor . visit ( & m_calendar ) ;
}
2022-05-06 19:28:56 +02:00
// nsMinInstant - nsPerDay
2022-04-01 20:58:27 +03:00
auto const DATETIME_NANOSECONDS_MIN = " -8640000086400000000000 " _sbigint ;
2022-05-06 19:28:56 +02:00
// nsMaxInstant + nsPerDay
2022-04-01 20:58:27 +03:00
auto const DATETIME_NANOSECONDS_MAX = " 8640000086400000000000 " _sbigint ;
2021-07-19 00:29:26 +03:00
2022-10-14 09:47:17 -04:00
// 5.5.1 ISODateTimeWithinLimits ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-isodatetimewithinlimits
bool iso_date_time_within_limits ( i32 year , u8 month , u8 day , u8 hour , u8 minute , u8 second , u16 millisecond , u16 microsecond , u16 nanosecond )
2021-07-19 00:29:26 +03:00
{
2022-07-10 01:22:34 +02:00
// 1. Assert: IsValidISODate(year, month, day) is true.
VERIFY ( is_valid_iso_date ( year , month , day ) ) ;
2022-10-14 09:47:17 -04:00
// 2. Let ns be ℝ (GetUTCEpochNanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)).
auto ns = get_utc_epoch_nanoseconds ( year , month , day , hour , minute , second , millisecond , microsecond , nanosecond ) ;
2021-07-19 00:29:26 +03:00
2022-07-10 01:22:34 +02:00
// 3. If ns ≤ nsMinInstant - nsPerDay, then
2022-04-29 19:10:21 +02:00
if ( ns < = DATETIME_NANOSECONDS_MIN ) {
2021-07-19 00:29:26 +03:00
// a. Return false.
return false ;
}
2022-07-10 01:22:34 +02:00
// 4. If ns ≥ nsMaxInstant + nsPerDay, then
2022-04-29 19:10:21 +02:00
if ( ns > = DATETIME_NANOSECONDS_MAX ) {
2021-07-19 00:29:26 +03:00
// a. Return false.
return false ;
}
2022-07-10 01:22:34 +02:00
// 5. Return true.
2021-07-19 00:29:26 +03:00
return true ;
}
2022-10-14 09:47:17 -04:00
// 5.5.2 InterpretTemporalDateTimeFields ( calendar, fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-interprettemporaldatetimefields
2022-08-20 08:52:42 +01:00
ThrowCompletionOr < ISODateTime > interpret_temporal_date_time_fields ( VM & vm , Object & calendar , Object & fields , Object const & options )
2021-08-22 23:16:42 +01:00
{
// 1. Let timeResult be ? ToTemporalTimeRecord(fields).
2022-08-20 08:52:42 +01:00
auto unregulated_time_result = TRY ( to_temporal_time_record ( vm , fields ) ) ;
2021-08-22 23:16:42 +01:00
2021-09-18 13:38:48 +02:00
// 2. Let overflow be ? ToTemporalOverflow(options).
2022-08-20 08:52:42 +01:00
auto overflow = TRY ( to_temporal_overflow ( vm , & options ) ) ;
2021-08-22 23:16:42 +01:00
2022-04-29 18:34:16 +02:00
// 3. Let temporalDate be ? CalendarDateFromFields(calendar, fields, options).
2022-08-20 08:52:42 +01:00
auto * temporal_date = TRY ( calendar_date_from_fields ( vm , calendar , fields , & options ) ) ;
2021-09-18 13:38:48 +02:00
2021-08-22 23:16:42 +01:00
// 4. Let timeResult be ? RegulateTime(timeResult.[[Hour]], timeResult.[[Minute]], timeResult.[[Second]], timeResult.[[Millisecond]], timeResult.[[Microsecond]], timeResult.[[Nanosecond]], overflow).
2022-08-20 08:52:42 +01:00
auto time_result = TRY ( regulate_time ( vm , * unregulated_time_result . hour , * unregulated_time_result . minute , * unregulated_time_result . second , * unregulated_time_result . millisecond , * unregulated_time_result . microsecond , * unregulated_time_result . nanosecond , overflow ) ) ;
2021-08-22 23:16:42 +01:00
// 5. Return the Record { [[Year]]: temporalDate.[[ISOYear]], [[Month]]: temporalDate.[[ISOMonth]], [[Day]]: temporalDate.[[ISODay]], [[Hour]]: timeResult.[[Hour]], [[Minute]]: timeResult.[[Minute]], [[Second]]: timeResult.[[Second]], [[Millisecond]]: timeResult.[[Millisecond]], [[Microsecond]]: timeResult.[[Microsecond]], [[Nanosecond]]: timeResult.[[Nanosecond]] }.
return ISODateTime {
. year = temporal_date - > iso_year ( ) ,
. month = temporal_date - > iso_month ( ) ,
. day = temporal_date - > iso_day ( ) ,
2021-09-16 02:08:03 +03:00
. hour = time_result . hour ,
. minute = time_result . minute ,
. second = time_result . second ,
. millisecond = time_result . millisecond ,
. microsecond = time_result . microsecond ,
. nanosecond = time_result . nanosecond ,
2021-08-22 23:16:42 +01:00
} ;
}
2022-10-14 09:47:17 -04:00
// 5.5.3 ToTemporalDateTime ( item [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldatetime
2022-08-20 08:52:42 +01:00
ThrowCompletionOr < PlainDateTime * > to_temporal_date_time ( VM & vm , Value item , Object const * options )
2021-08-22 23:16:42 +01:00
{
2022-04-06 23:56:57 +01:00
// 1. If options is not present, set options to undefined.
// 2. Assert: Type(options) is Object or Undefined.
2021-08-22 23:16:42 +01:00
Object * calendar ;
ISODateTime result ;
2022-04-06 23:56:57 +01:00
// 3. If Type(item) is Object, then
2021-08-22 23:16:42 +01:00
if ( item . is_object ( ) ) {
auto & item_object = item . as_object ( ) ;
// a. If item has an [[InitializedTemporalDateTime]] internal slot, then
if ( is < PlainDateTime > ( item_object ) ) {
// i. Return item.
return & static_cast < PlainDateTime & > ( item_object ) ;
}
// b. If item has an [[InitializedTemporalZonedDateTime]] internal slot, then
if ( is < ZonedDateTime > ( item_object ) ) {
auto & zoned_date_time = static_cast < ZonedDateTime & > ( item_object ) ;
2022-07-05 19:25:01 +02:00
// i. Perform ? ToTemporalOverflow(options).
2022-08-20 08:52:42 +01:00
( void ) TRY ( to_temporal_overflow ( vm , options ) ) ;
2022-07-05 19:25:01 +02:00
// ii. Let instant be ! CreateTemporalInstant(item.[[Nanoseconds]]).
2022-08-20 08:52:42 +01:00
auto * instant = create_temporal_instant ( vm , zoned_date_time . nanoseconds ( ) ) . release_value ( ) ;
2021-08-22 23:16:42 +01:00
2022-07-05 19:25:01 +02:00
// iii. Return ? BuiltinTimeZoneGetPlainDateTimeFor(item.[[TimeZone]], instant, item.[[Calendar]]).
2022-08-20 08:52:42 +01:00
return builtin_time_zone_get_plain_date_time_for ( vm , & zoned_date_time . time_zone ( ) , * instant , zoned_date_time . calendar ( ) ) ;
2021-08-22 23:16:42 +01:00
}
// c. If item has an [[InitializedTemporalDate]] internal slot, then
if ( is < PlainDate > ( item_object ) ) {
auto & plain_date = static_cast < PlainDate & > ( item_object ) ;
2022-07-05 19:25:01 +02:00
// i. Perform ? ToTemporalOverflow(options).
2022-08-20 08:52:42 +01:00
( void ) TRY ( to_temporal_overflow ( vm , options ) ) ;
2022-07-05 19:25:01 +02:00
// ii. Return ? CreateTemporalDateTime(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], 0, 0, 0, 0, 0, 0, item.[[Calendar]]).
2022-08-20 08:52:42 +01:00
return create_temporal_date_time ( vm , plain_date . iso_year ( ) , plain_date . iso_month ( ) , plain_date . iso_day ( ) , 0 , 0 , 0 , 0 , 0 , 0 , plain_date . calendar ( ) ) ;
2021-08-22 23:16:42 +01:00
}
// d. Let calendar be ? GetTemporalCalendarWithISODefault(item).
2022-08-20 08:52:42 +01:00
calendar = TRY ( get_temporal_calendar_with_iso_default ( vm , item_object ) ) ;
2021-08-22 23:16:42 +01:00
// e. Let fieldNames be ? CalendarFields(calendar, « "day", "hour", "microsecond", "millisecond", "minute", "month", "monthCode", "nanosecond", "second", "year" »).
2022-08-20 08:52:42 +01:00
auto field_names = TRY ( calendar_fields ( vm , * calendar , { " day " sv , " hour " sv , " microsecond " sv , " millisecond " sv , " minute " sv , " month " sv , " monthCode " sv , " nanosecond " sv , " second " sv , " year " sv } ) ) ;
2021-08-22 23:16:42 +01:00
// f. Let fields be ? PrepareTemporalFields(item, fieldNames, «»).
2022-08-20 08:52:42 +01:00
auto * fields = TRY ( prepare_temporal_fields ( vm , item_object , field_names , Vector < StringView > { } ) ) ;
2021-08-22 23:16:42 +01:00
// g. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options).
2022-08-20 08:52:42 +01:00
result = TRY ( interpret_temporal_date_time_fields ( vm , * calendar , * fields , * options ) ) ;
2021-08-22 23:16:42 +01:00
}
2022-04-06 23:56:57 +01:00
// 4. Else,
2021-08-22 23:16:42 +01:00
else {
// a. Perform ? ToTemporalOverflow(options).
2022-08-20 08:52:42 +01:00
( void ) TRY ( to_temporal_overflow ( vm , options ) ) ;
2021-08-22 23:16:42 +01:00
// b. Let string be ? ToString(item).
2023-01-13 10:29:02 -05:00
auto string = TRY ( item . to_deprecated_string ( vm ) ) ;
2021-08-22 23:16:42 +01:00
// c. Let result be ? ParseTemporalDateTimeString(string).
2022-08-20 08:52:42 +01:00
result = TRY ( parse_temporal_date_time_string ( vm , string ) ) ;
2021-08-22 23:16:42 +01:00
2022-04-29 19:03:57 +02:00
// d. Assert: IsValidISODate(result.[[Year]], result.[[Month]], result.[[Day]]) is true.
2021-08-22 23:16:42 +01:00
VERIFY ( is_valid_iso_date ( result . year , result . month , result . day ) ) ;
2022-04-29 19:03:57 +02:00
// e. Assert: IsValidTime(result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]]) is true.
2021-08-22 23:16:42 +01:00
VERIFY ( is_valid_time ( result . hour , result . minute , result . second , result . millisecond , result . microsecond , result . nanosecond ) ) ;
// f. Let calendar be ? ToTemporalCalendarWithISODefault(result.[[Calendar]]).
2022-12-06 22:17:27 +00:00
calendar = TRY ( to_temporal_calendar_with_iso_default ( vm , result . calendar . has_value ( ) ? PrimitiveString : : create ( vm , * result . calendar ) : js_undefined ( ) ) ) ;
2021-08-22 23:16:42 +01:00
}
2022-04-06 23:56:57 +01:00
// 5. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], calendar).
2022-08-20 08:52:42 +01:00
return create_temporal_date_time ( vm , result . year , result . month , result . day , result . hour , result . minute , result . second , result . millisecond , result . microsecond , result . nanosecond , * calendar ) ;
2021-08-22 23:16:42 +01:00
}
2022-10-14 09:47:17 -04:00
// 5.5.4 BalanceISODateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-balanceisodatetime
2021-07-27 00:21:16 +01:00
ISODateTime balance_iso_date_time ( i32 year , u8 month , u8 day , u8 hour , u8 minute , u8 second , u16 millisecond , u16 microsecond , i64 nanosecond )
{
// NOTE: The only use of this AO is in BuiltinTimeZoneGetPlainDateTimeFor, where we know that all values
// but `nanosecond` are in their usual range, hence why that's the only outlier here. The range for that
// is -86400000000000 to 86400000000999, so an i32 is not enough.
// 1. Assert: year, month, day, hour, minute, second, millisecond, microsecond, and nanosecond are integers.
// 2. Let balancedTime be ! BalanceTime(hour, minute, second, millisecond, microsecond, nanosecond).
auto balanced_time = balance_time ( hour , minute , second , millisecond , microsecond , nanosecond ) ;
2022-05-06 20:57:55 +02:00
// 3. Let balancedDate be BalanceISODate(year, month, day + balancedTime.[[Days]]).
2021-07-27 00:21:16 +01:00
auto balanced_date = balance_iso_date ( year , month , day + balanced_time . days ) ;
// 4. Return the Record { [[Year]]: balancedDate.[[Year]], [[Month]]: balancedDate.[[Month]], [[Day]]: balancedDate.[[Day]], [[Hour]]: balancedTime.[[Hour]], [[Minute]]: balancedTime.[[Minute]], [[Second]]: balancedTime.[[Second]], [[Millisecond]]: balancedTime.[[Millisecond]], [[Microsecond]]: balancedTime.[[Microsecond]], [[Nanosecond]]: balancedTime.[[Nanosecond]] }.
return ISODateTime { . year = balanced_date . year , . month = balanced_date . month , . day = balanced_date . day , . hour = balanced_time . hour , . minute = balanced_time . minute , . second = balanced_time . second , . millisecond = balanced_time . millisecond , . microsecond = balanced_time . microsecond , . nanosecond = balanced_time . nanosecond } ;
}
2022-10-14 09:47:17 -04:00
// 5.5.5 CreateTemporalDateTime ( isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond, calendar [ , newTarget ] ), https://tc39.es/proposal-temporal/#sec-temporal-createtemporaldatetime
2022-08-20 08:52:42 +01:00
ThrowCompletionOr < PlainDateTime * > create_temporal_date_time ( VM & vm , i32 iso_year , u8 iso_month , u8 iso_day , u8 hour , u8 minute , u8 second , u16 millisecond , u16 microsecond , u16 nanosecond , Object & calendar , FunctionObject const * new_target )
2021-07-22 19:47:07 +01:00
{
2022-08-20 08:52:42 +01:00
auto & realm = * vm . current_realm ( ) ;
2021-07-22 19:47:07 +01:00
// 1. Assert: isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, and nanosecond are integers.
// 2. Assert: Type(calendar) is Object.
2022-04-29 19:03:57 +02:00
// 3. If IsValidISODate(isoYear, isoMonth, isoDay) is false, throw a RangeError exception.
2021-09-17 21:03:49 +02:00
if ( ! is_valid_iso_date ( iso_year , iso_month , iso_day ) )
2022-08-16 20:33:17 +01:00
return vm . throw_completion < RangeError > ( ErrorType : : TemporalInvalidPlainDateTime ) ;
2021-07-22 19:47:07 +01:00
2022-04-29 19:03:57 +02:00
// 4. If IsValidTime(hour, minute, second, millisecond, microsecond, nanosecond) is false, throw a RangeError exception.
2021-09-17 21:03:49 +02:00
if ( ! is_valid_time ( hour , minute , second , millisecond , microsecond , nanosecond ) )
2022-08-16 20:33:17 +01:00
return vm . throw_completion < RangeError > ( ErrorType : : TemporalInvalidPlainDateTime ) ;
2021-07-22 19:47:07 +01:00
2022-04-29 19:03:57 +02:00
// 5. If ISODateTimeWithinLimits(isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond) is false, then
2022-10-14 09:47:17 -04:00
if ( ! iso_date_time_within_limits ( iso_year , iso_month , iso_day , hour , minute , second , millisecond , microsecond , nanosecond ) ) {
2021-07-22 19:47:07 +01:00
// a. Throw a RangeError exception.
2022-08-16 20:33:17 +01:00
return vm . throw_completion < RangeError > ( ErrorType : : TemporalInvalidPlainDateTime ) ;
2021-07-22 19:47:07 +01:00
}
2022-03-10 17:04:46 +01:00
// 6. If newTarget is not present, set newTarget to %Temporal.PlainDateTime%.
2021-07-22 19:47:07 +01:00
if ( ! new_target )
2022-08-27 00:54:55 +01:00
new_target = realm . intrinsics ( ) . temporal_plain_date_time_constructor ( ) ;
2021-07-22 19:47:07 +01:00
// 7. Let object be ? OrdinaryCreateFromConstructor(newTarget, "%Temporal.PlainDateTime.prototype%", « [[InitializedTemporalDateTime]], [[ISOYear]], [[ISOMonth]], [[ISODay]], [[ISOHour]], [[ISOMinute]], [[ISOSecond]], [[ISOMillisecond]], [[ISOMicrosecond]], [[ISONanosecond]], [[Calendar]] »).
// 8. Set object.[[ISOYear]] to isoYear.
// 9. Set object.[[ISOMonth]] to isoMonth.
// 10. Set object.[[ISODay]] to isoDay.
// 11. Set object.[[ISOHour]] to hour.
// 12. Set object.[[ISOMinute]] to minute.
// 13. Set object.[[ISOSecond]] to second.
// 14. Set object.[[ISOMillisecond]] to millisecond.
// 15. Set object.[[ISOMicrosecond]] to microsecond.
// 16. Set object.[[ISONanosecond]] to nanosecond.
// 17. Set object.[[Calendar]] to calendar.
2022-12-14 18:34:32 +00:00
auto object = TRY ( ordinary_create_from_constructor < PlainDateTime > ( vm , * new_target , & Intrinsics : : temporal_plain_date_prototype , iso_year , iso_month , iso_day , hour , minute , second , millisecond , microsecond , nanosecond , calendar ) ) ;
2021-07-22 19:47:07 +01:00
// 18. Return object.
2022-12-14 18:34:32 +00:00
return object . ptr ( ) ;
2021-07-22 19:47:07 +01:00
}
2022-10-14 09:47:17 -04:00
// 5.5.6 TemporalDateTimeToString ( isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond, calendar, precision, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-temporaldatetimetostring
2022-12-04 18:02:33 +00:00
ThrowCompletionOr < DeprecatedString > temporal_date_time_to_string ( VM & vm , i32 iso_year , u8 iso_month , u8 iso_day , u8 hour , u8 minute , u8 second , u16 millisecond , u16 microsecond , u16 nanosecond , Object const * calendar , Variant < StringView , u8 > const & precision , StringView show_calendar )
2021-08-31 00:15:36 +01:00
{
// 1. Assert: isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, and nanosecond are integers.
// 2. Let year be ! PadISOYear(isoYear).
2022-04-12 22:20:33 +01:00
// 3. Let month be ToZeroPaddedDecimalString(isoMonth, 2).
// 4. Let day be ToZeroPaddedDecimalString(isoDay, 2).
// 5. Let hour be ToZeroPaddedDecimalString(hour, 2).
// 6. Let minute be ToZeroPaddedDecimalString(minute, 2).
2021-08-31 00:15:36 +01:00
// 7. Let seconds be ! FormatSecondsStringPart(second, millisecond, microsecond, nanosecond, precision).
2023-01-26 14:15:13 +00:00
auto seconds = MUST_OR_THROW_OOM ( format_seconds_string_part ( vm , second , millisecond , microsecond , nanosecond , precision ) ) ;
2021-08-31 00:15:36 +01:00
2022-08-08 14:48:48 +01:00
// 8. Let calendarString be ? MaybeFormatCalendarAnnotation(calendar, showCalendar).
auto calendar_string = TRY ( maybe_format_calendar_annotation ( vm , calendar , show_calendar ) ) ;
2021-08-31 00:15:36 +01:00
2022-08-08 14:48:48 +01:00
// 9. Return the string-concatenation of year, the code unit 0x002D (HYPHEN-MINUS), month, the code unit 0x002D (HYPHEN-MINUS), day, 0x0054 (LATIN CAPITAL LETTER T), hour, the code unit 0x003A (COLON), minute, seconds, and calendarString.
2022-12-04 18:02:33 +00:00
return DeprecatedString : : formatted ( " {}-{:02}-{:02}T{:02}:{:02}{}{} " , pad_iso_year ( iso_year ) , iso_month , iso_day , hour , minute , seconds , calendar_string ) ;
2021-08-31 00:15:36 +01:00
}
2022-10-14 09:47:17 -04:00
// 5.5.7 CompareISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2 ), https://tc39.es/proposal-temporal/#sec-temporal-compareisodatetime
2021-08-27 16:33:15 +03:00
i8 compare_iso_date_time ( i32 year1 , u8 month1 , u8 day1 , u8 hour1 , u8 minute1 , u8 second1 , u16 millisecond1 , u16 microsecond1 , u16 nanosecond1 , i32 year2 , u8 month2 , u8 day2 , u8 hour2 , u8 minute2 , u8 second2 , u16 millisecond2 , u16 microsecond2 , u16 nanosecond2 )
{
// 1. Assert: y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, and ns2 are integers.
// 2. Let dateResult be ! CompareISODate(y1, mon1, d1, y2, mon2, d2).
auto date_result = compare_iso_date ( year1 , month1 , day1 , year2 , month2 , day2 ) ;
// 3. If dateResult is not 0, then
if ( date_result ! = 0 ) {
// a. Return dateResult.
return date_result ;
}
// 4. Return ! CompareTemporalTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2).
return compare_temporal_time ( hour1 , minute1 , second1 , millisecond1 , microsecond1 , nanosecond1 , hour2 , minute2 , second2 , millisecond2 , microsecond2 , nanosecond2 ) ;
}
2022-10-14 09:47:17 -04:00
// 5.5.8 AddDateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, calendar, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, options ), https://tc39.es/proposal-temporal/#sec-temporal-adddatetime
2022-08-20 08:52:42 +01:00
ThrowCompletionOr < TemporalPlainDateTime > add_date_time ( VM & vm , i32 year , u8 month , u8 day , u8 hour , u8 minute , u8 second , u16 millisecond , u16 microsecond , u16 nanosecond , Object & calendar , double years , double months , double weeks , double days , double hours , double minutes , double seconds , double milliseconds , double microseconds , double nanoseconds , Object * options )
2021-11-01 14:20:06 +01:00
{
2022-06-23 23:13:31 +01:00
// 1. Assert: ISODateTimeWithinLimits(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond) is true.
2022-10-14 09:47:17 -04:00
VERIFY ( iso_date_time_within_limits ( year , month , day , hour , minute , second , millisecond , microsecond , nanosecond ) ) ;
2022-06-23 23:13:31 +01:00
// 2. Let timeResult be ! AddTime(hour, minute, second, millisecond, microsecond, nanosecond, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
2021-11-01 14:20:06 +01:00
auto time_result = add_time ( hour , minute , second , millisecond , microsecond , nanosecond , hours , minutes , seconds , milliseconds , microseconds , nanoseconds ) ;
2022-06-23 23:13:31 +01:00
// 3. Let datePart be ! CreateTemporalDate(year, month, day, calendar).
2022-08-20 08:52:42 +01:00
auto * date_part = MUST ( create_temporal_date ( vm , year , month , day , calendar ) ) ;
2021-11-01 14:20:06 +01:00
2022-06-23 23:13:31 +01:00
// 4. Let dateDuration be ? CreateTemporalDuration(years, months, weeks, days + timeResult.[[Days]], 0, 0, 0, 0, 0, 0).
2022-08-20 08:52:42 +01:00
auto * date_duration = TRY ( create_temporal_duration ( vm , years , months , weeks , days + time_result . days , 0 , 0 , 0 , 0 , 0 , 0 ) ) ;
2021-11-01 14:20:06 +01:00
2022-06-23 23:13:31 +01:00
// 5. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options).
2022-08-20 08:52:42 +01:00
auto * added_date = TRY ( calendar_date_add ( vm , calendar , date_part , * date_duration , options ) ) ;
2021-11-01 14:20:06 +01:00
2022-06-23 23:13:31 +01:00
// 6. Return the Record { [[Year]]: addedDate.[[ISOYear]], [[Month]]: addedDate.[[ISOMonth]], [[Day]]: addedDate.[[ISODay]], [[Hour]]: timeResult.[[Hour]], [[Minute]]: timeResult.[[Minute]], [[Second]]: timeResult.[[Second]], [[Millisecond]]: timeResult.[[Millisecond]], [[Microsecond]]: timeResult.[[Microsecond]], [[Nanosecond]]: timeResult.[[Nanosecond]] }.
2021-11-01 14:20:06 +01:00
return TemporalPlainDateTime { . year = added_date - > iso_year ( ) , . month = added_date - > iso_month ( ) , . day = added_date - > iso_day ( ) , . hour = time_result . hour , . minute = time_result . minute , . second = time_result . second , . millisecond = time_result . millisecond , . microsecond = time_result . microsecond , . nanosecond = time_result . nanosecond } ;
}
2022-10-14 09:47:17 -04:00
// 5.5.9 RoundISODateTime ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond, increment, unit, roundingMode [ , dayLength ] ), https://tc39.es/proposal-temporal/#sec-temporal-roundisodatetime
ISODateTime round_iso_date_time ( i32 year , u8 month , u8 day , u8 hour , u8 minute , u8 second , u16 millisecond , u16 microsecond , u16 nanosecond , u64 increment , StringView unit , StringView rounding_mode , Optional < double > day_length )
2021-11-03 01:51:35 +00:00
{
// 1. Assert: year, month, day, hour, minute, second, millisecond, microsecond, and nanosecond are integers.
2022-06-23 23:04:44 +01:00
// 2. Assert: ISODateTimeWithinLimits(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond) is true.
2022-10-14 09:47:17 -04:00
VERIFY ( iso_date_time_within_limits ( year , month , day , hour , minute , second , millisecond , microsecond , nanosecond ) ) ;
2022-06-23 23:04:44 +01:00
// 3. If dayLength is not present, set dayLength to nsPerDay.
2021-11-03 01:51:35 +00:00
if ( ! day_length . has_value ( ) )
2022-05-06 19:28:56 +02:00
day_length = ns_per_day ;
2021-11-03 01:51:35 +00:00
2022-06-23 23:04:44 +01:00
// 4. Let roundedTime be ! RoundTime(hour, minute, second, millisecond, microsecond, nanosecond, increment, unit, roundingMode, dayLength).
2021-11-03 01:51:35 +00:00
auto rounded_time = round_time ( hour , minute , second , millisecond , microsecond , nanosecond , increment , unit , rounding_mode , day_length ) ;
2022-06-23 23:04:44 +01:00
// 5. Let balanceResult be BalanceISODate(year, month, day + roundedTime.[[Days]]).
2021-11-03 01:51:35 +00:00
auto balance_result = balance_iso_date ( year , month , day + rounded_time . days ) ;
2022-06-23 23:04:44 +01:00
// 6. Return the Record { [[Year]]: balanceResult.[[Year]], [[Month]]: balanceResult.[[Month]], [[Day]]: balanceResult.[[Day]], [[Hour]]: roundedTime.[[Hour]], [[Minute]]: roundedTime.[[Minute]], [[Second]]: roundedTime.[[Second]], [[Millisecond]]: roundedTime.[[Millisecond]], [[Microsecond]]: roundedTime.[[Microsecond]], [[Nanosecond]]: roundedTime.[[Nanosecond]] }.
2021-11-03 01:51:35 +00:00
return ISODateTime { . year = balance_result . year , . month = balance_result . month , . day = balance_result . day , . hour = rounded_time . hour , . minute = rounded_time . minute , . second = rounded_time . second , . millisecond = rounded_time . millisecond , . microsecond = rounded_time . microsecond , . nanosecond = rounded_time . nanosecond } ;
}
2022-10-14 09:47:17 -04:00
// 5.5.10 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendar, largestUnit, options ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodatetime
2022-08-20 08:52:42 +01:00
ThrowCompletionOr < DurationRecord > difference_iso_date_time ( VM & vm , i32 year1 , u8 month1 , u8 day1 , u8 hour1 , u8 minute1 , u8 second1 , u16 millisecond1 , u16 microsecond1 , u16 nanosecond1 , i32 year2 , u8 month2 , u8 day2 , u8 hour2 , u8 minute2 , u8 second2 , u16 millisecond2 , u16 microsecond2 , u16 nanosecond2 , Object & calendar , StringView largest_unit , Object const & options )
2021-11-02 00:14:47 +01:00
{
2022-06-27 23:10:37 +01:00
// 1. Assert: ISODateTimeWithinLimits(y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1) is true.
2022-10-14 09:47:17 -04:00
VERIFY ( iso_date_time_within_limits ( year1 , month1 , day1 , hour1 , minute1 , second1 , millisecond1 , microsecond1 , nanosecond1 ) ) ;
2022-06-27 23:10:37 +01:00
// 2. Assert: ISODateTimeWithinLimits(y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2) is true.
2022-10-14 09:47:17 -04:00
VERIFY ( iso_date_time_within_limits ( year2 , month2 , day2 , hour2 , minute2 , second2 , millisecond2 , microsecond2 , nanosecond2 ) ) ;
2022-06-27 23:10:37 +01:00
// 3. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2).
2022-08-20 08:52:42 +01:00
auto time_difference = difference_time ( vm , hour1 , minute1 , second1 , millisecond1 , microsecond1 , nanosecond1 , hour2 , minute2 , second2 , millisecond2 , microsecond2 , nanosecond2 ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:10:37 +01:00
// 4. Let timeSign be ! DurationSign(0, 0, 0, 0, timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]).
2022-06-27 23:06:29 +01:00
auto time_sign = duration_sign ( 0 , 0 , 0 , 0 , time_difference . hours , time_difference . minutes , time_difference . seconds , time_difference . milliseconds , time_difference . microseconds , time_difference . nanoseconds ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:10:37 +01:00
// 5. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1).
2021-11-02 00:14:47 +01:00
auto date_sign = compare_iso_date ( year2 , month2 , day2 , year1 , month1 , day1 ) ;
2022-06-27 23:11:57 +01:00
// 6. Let adjustedDate be CreateISODateRecord(y1, mon1, d1).
auto adjusted_date = create_iso_date_record ( year1 , month1 , day1 ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:10:37 +01:00
// 7. If timeSign is -dateSign, then
2021-11-02 00:14:47 +01:00
if ( time_sign = = - date_sign ) {
2022-05-06 20:57:55 +02:00
// a. Set adjustedDate to BalanceISODate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]] - timeSign).
2022-03-10 17:16:28 +01:00
adjusted_date = balance_iso_date ( adjusted_date . year , adjusted_date . month , adjusted_date . day - time_sign ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:12:26 +01:00
// b. Set timeDifference to ! BalanceDuration(-timeSign, timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
2022-08-26 00:58:37 +02:00
time_difference = MUST ( balance_duration ( vm , - time_sign , time_difference . hours , time_difference . minutes , time_difference . seconds , time_difference . milliseconds , time_difference . microseconds , Crypto : : SignedBigInteger { time_difference . nanoseconds } , largest_unit ) ) ;
2021-11-02 00:14:47 +01:00
}
2022-06-27 23:13:41 +01:00
// 8. Let date1 be ! CreateTemporalDate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]], calendar).
2022-08-20 08:52:42 +01:00
auto * date1 = MUST ( create_temporal_date ( vm , adjusted_date . year , adjusted_date . month , adjusted_date . day , calendar ) ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:13:41 +01:00
// 9. Let date2 be ! CreateTemporalDate(y2, mon2, d2, calendar).
2022-08-20 08:52:42 +01:00
auto * date2 = MUST ( create_temporal_date ( vm , year2 , month2 , day2 , calendar ) ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:10:37 +01:00
// 10. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
2021-11-02 00:14:47 +01:00
auto date_largest_unit = larger_of_two_temporal_units ( " day " sv , largest_unit ) ;
2022-06-27 23:10:37 +01:00
// 11. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit).
2023-01-26 14:07:33 +00:00
auto * until_options = TRY ( merge_largest_unit_option ( vm , options , TRY_OR_THROW_OOM ( vm , String : : from_utf8 ( date_largest_unit ) ) ) ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:10:37 +01:00
// 12. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions).
2022-08-20 08:52:42 +01:00
auto * date_difference = TRY ( calendar_date_until ( vm , calendar , date1 , date2 , * until_options ) ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:10:37 +01:00
// 13. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
2022-08-26 00:58:37 +02:00
auto balance_result = TRY ( balance_duration ( vm , date_difference - > days ( ) , time_difference . hours , time_difference . minutes , time_difference . seconds , time_difference . milliseconds , time_difference . microseconds , Crypto : : SignedBigInteger { time_difference . nanoseconds } , largest_unit ) ) ;
2021-11-02 00:14:47 +01:00
2022-06-27 23:10:37 +01:00
// 14. Return ! CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]]).
2022-03-10 17:16:28 +01:00
return create_duration_record ( date_difference - > years ( ) , date_difference - > months ( ) , date_difference - > weeks ( ) , balance_result . days , balance_result . hours , balance_result . minutes , balance_result . seconds , balance_result . milliseconds , balance_result . microseconds , balance_result . nanoseconds ) ;
2021-11-02 00:14:47 +01:00
}
2022-10-14 09:47:17 -04:00
// 5.5.11 DifferenceTemporalPlainDateTime ( operation, dateTime, other, options ), https://tc39.es/proposal-temporal/#sec-temporal-differencetemporalplaindatetime
2022-08-20 08:52:42 +01:00
ThrowCompletionOr < Duration * > difference_temporal_plain_date_time ( VM & vm , DifferenceOperation operation , PlainDateTime & date_time , Value other_value , Value options_value )
2022-05-07 13:32:19 +02:00
{
// 1. If operation is since, let sign be -1. Otherwise, let sign be 1.
i8 sign = operation = = DifferenceOperation : : Since ? - 1 : 1 ;
// 2. Set other to ? ToTemporalDateTime(other).
2022-08-20 08:52:42 +01:00
auto * other = TRY ( to_temporal_date_time ( vm , other_value ) ) ;
2022-05-07 13:32:19 +02:00
// 3. If ? CalendarEquals(dateTime.[[Calendar]], other.[[Calendar]]) is false, throw a RangeError exception.
2022-08-20 08:52:42 +01:00
if ( ! TRY ( calendar_equals ( vm , date_time . calendar ( ) , other - > calendar ( ) ) ) )
2022-08-16 20:33:17 +01:00
return vm . throw_completion < RangeError > ( ErrorType : : TemporalDifferentCalendars ) ;
2022-05-07 13:32:19 +02:00
2022-06-24 00:27:29 +01:00
// 4. Let settings be ? GetDifferenceSettings(operation, options, datetime, « », "nanosecond", "day").
2022-08-20 08:52:42 +01:00
auto settings = TRY ( get_difference_settings ( vm , operation , options_value , UnitGroup : : DateTime , { } , { " nanosecond " sv } , " day " sv ) ) ;
2022-05-07 13:32:19 +02:00
2022-06-24 00:27:29 +01:00
// 5. Let diff be ? DifferenceISODateTime(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]], other.[[ISOYear]], other.[[ISOMonth]], other.[[ISODay]], other.[[ISOHour]], other.[[ISOMinute]], other.[[ISOSecond]], other.[[ISOMillisecond]], other.[[ISOMicrosecond]], other.[[ISONanosecond]], dateTime.[[Calendar]], settings.[[LargestUnit]], settings.[[Options]]).
2022-08-20 08:52:42 +01:00
auto diff = TRY ( difference_iso_date_time ( vm , date_time . iso_year ( ) , date_time . iso_month ( ) , date_time . iso_day ( ) , date_time . iso_hour ( ) , date_time . iso_minute ( ) , date_time . iso_second ( ) , date_time . iso_millisecond ( ) , date_time . iso_microsecond ( ) , date_time . iso_nanosecond ( ) , other - > iso_year ( ) , other - > iso_month ( ) , other - > iso_day ( ) , other - > iso_hour ( ) , other - > iso_minute ( ) , other - > iso_second ( ) , other - > iso_millisecond ( ) , other - > iso_microsecond ( ) , other - > iso_nanosecond ( ) , date_time . calendar ( ) , settings . largest_unit , settings . options ) ) ;
2022-05-07 13:32:19 +02:00
2022-06-24 00:27:29 +01:00
// 6. Let relativeTo be ! CreateTemporalDate(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[Calendar]]).
2022-08-20 08:52:42 +01:00
auto * relative_to = MUST ( create_temporal_date ( vm , date_time . iso_year ( ) , date_time . iso_month ( ) , date_time . iso_day ( ) , date_time . calendar ( ) ) ) ;
2022-05-07 13:32:19 +02:00
2022-06-24 00:27:29 +01:00
// 7. Let roundResult be (? RoundDuration(diff.[[Years]], diff.[[Months]], diff.[[Weeks]], diff.[[Days]], diff.[[Hours]], diff.[[Minutes]], diff.[[Seconds]], diff.[[Milliseconds]], diff.[[Microseconds]], diff.[[Nanoseconds]], settings.[[RoundingIncrement]], settings.[[SmallestUnit]], settings.[[RoundingMode]], relativeTo)).[[DurationRecord]].
2022-08-20 08:52:42 +01:00
auto round_result = TRY ( round_duration ( vm , diff . years , diff . months , diff . weeks , diff . days , diff . hours , diff . minutes , diff . seconds , diff . milliseconds , diff . microseconds , diff . nanoseconds , settings . rounding_increment , settings . smallest_unit , settings . rounding_mode , relative_to ) ) . duration_record ;
2022-05-07 13:32:19 +02:00
2022-06-24 00:27:29 +01:00
// 8. Let result be ? BalanceDuration(roundResult.[[Days]], roundResult.[[Hours]], roundResult.[[Minutes]], roundResult.[[Seconds]], roundResult.[[Milliseconds]], roundResult.[[Microseconds]], roundResult.[[Nanoseconds]], settings.[[LargestUnit]]).
2022-08-26 00:49:50 +02:00
auto result = MUST ( balance_duration ( vm , round_result . days , round_result . hours , round_result . minutes , round_result . seconds , round_result . milliseconds , round_result . microseconds , Crypto : : SignedBigInteger { round_result . nanoseconds } , settings . largest_unit ) ) ;
2022-05-07 13:32:19 +02:00
2022-06-24 00:27:29 +01:00
// 9. Return ! CreateTemporalDuration(sign × roundResult.[[Years]], sign × roundResult.[[Months]], sign × roundResult.[[Weeks]], sign × result.[[Days]], sign × result.[[Hours]], sign × result.[[Minutes]], sign × result.[[Seconds]], sign × result.[[Milliseconds]], sign × result.[[Microseconds]], sign × result.[[Nanoseconds]]).
2022-08-20 08:52:42 +01:00
return MUST ( create_temporal_duration ( vm , sign * round_result . years , sign * round_result . months , sign * round_result . weeks , sign * result . days , sign * result . hours , sign * result . minutes , sign * result . seconds , sign * result . milliseconds , sign * result . microseconds , sign * result . nanoseconds ) ) ;
2022-05-07 13:32:19 +02:00
}
2022-10-14 09:47:17 -04:00
// 5.5.12 AddDurationToOrSubtractDurationFromPlainDateTime ( operation, dateTime, temporalDurationLike, options ), https://tc39.es/proposal-temporal/#sec-temporal-adddurationtoorsubtractdurationfromplaindatetime
2022-08-20 08:52:42 +01:00
ThrowCompletionOr < PlainDateTime * > add_duration_to_or_subtract_duration_from_plain_date_time ( VM & vm , ArithmeticOperation operation , PlainDateTime & date_time , Value temporal_duration_like , Value options_value )
2022-05-06 19:01:15 +02:00
{
// 1. If operation is subtract, let sign be -1. Otherwise, let sign be 1.
i8 sign = operation = = ArithmeticOperation : : Subtract ? - 1 : 1 ;
// 2. Let duration be ? ToTemporalDurationRecord(temporalDurationLike).
2022-08-20 08:52:42 +01:00
auto duration = TRY ( to_temporal_duration_record ( vm , temporal_duration_like ) ) ;
2022-05-06 19:01:15 +02:00
// 3. Set options to ? GetOptionsObject(options).
2022-08-20 08:52:42 +01:00
auto * options = TRY ( get_options_object ( vm , options_value ) ) ;
2022-05-06 19:01:15 +02:00
// 4. Let result be ? AddDateTime(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]], dateTime.[[Calendar]], sign × duration.[[Years]], sign × duration.[[Months]], sign × duration.[[Weeks]], sign × duration.[[Days]], sign × duration.[[Hours]], sign × duration.[[Minutes]], sign × duration.[[Seconds]], sign × duration.[[Milliseconds]], sign × duration.[[Microseconds]], sign × duration.[[Nanoseconds]], options).
2022-08-20 08:52:42 +01:00
auto result = TRY ( add_date_time ( vm , date_time . iso_year ( ) , date_time . iso_month ( ) , date_time . iso_day ( ) , date_time . iso_hour ( ) , date_time . iso_minute ( ) , date_time . iso_second ( ) , date_time . iso_millisecond ( ) , date_time . iso_microsecond ( ) , date_time . iso_nanosecond ( ) , date_time . calendar ( ) , sign * duration . years , sign * duration . months , sign * duration . weeks , sign * duration . days , sign * duration . hours , sign * duration . minutes , sign * duration . seconds , sign * duration . milliseconds , sign * duration . microseconds , sign * duration . nanoseconds , options ) ) ;
2022-05-06 19:01:15 +02:00
// 5. Assert: IsValidISODate(result.[[Year]], result.[[Month]], result.[[Day]]) is true.
VERIFY ( is_valid_iso_date ( result . year , result . month , result . day ) ) ;
// 6. Assert: IsValidTime(result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]]) is true.
VERIFY ( is_valid_time ( result . hour , result . minute , result . second , result . millisecond , result . microsecond , result . nanosecond ) ) ;
// 7. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], dateTime.[[Calendar]]).
2022-08-20 08:52:42 +01:00
return create_temporal_date_time ( vm , result . year , result . month , result . day , result . hour , result . minute , result . second , result . millisecond , result . microsecond , result . nanosecond , date_time . calendar ( ) ) ;
2022-05-06 19:01:15 +02:00
}
2021-07-11 21:04:11 +03:00
}