29#include "unicode/calendar.h"
30#include "unicode/unistr.h"
60struct UnbalancedTimeRecord {
69using temporal::DateRecord;
70using temporal::DateTimeRecord;
71using temporal::TimeRecord;
73struct DateRecordWithCalendar {
78struct TimeRecordWithCalendar {
83struct TimeZoneRecord {
86 DirectHandle<Object> name;
89struct DateTimeRecordWithCalendar {
102using temporal::DurationRecord;
104using temporal::TimeDurationRecord;
106struct DurationRecordWithRemainder {
112struct DateDurationRecord {
118 static Maybe<DateDurationRecord> Create(Isolate* isolate,
double years,
119 double months,
double weeks,
129enum class Disambiguation { kCompatible, kEarlier, kLater, kReject };
132enum class ShowOverflow { kConstrain, kReject };
137enum class ShowTimeZone {
kAuto, kNever };
138Maybe<ShowTimeZone> ToShowTimeZoneNameOption(Isolate* isolate,
139 DirectHandle<JSReceiver> options,
140 const char* method_name) {
144 isolate, options,
"timeZoneName", method_name, {
"auto",
"never"},
145 {ShowTimeZone::kAuto, ShowTimeZone::kNever}, ShowTimeZone::kAuto);
149enum class ShowOffset {
kAuto, kNever };
150Maybe<ShowOffset> ToShowOffsetOption(Isolate* isolate,
151 DirectHandle<JSReceiver> options,
152 const char* method_name) {
156 isolate, options,
"offset", method_name, {
"auto",
"never"},
157 {ShowOffset::kAuto, ShowOffset::kNever}, ShowOffset::kAuto);
160enum class Precision { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9,
kAuto, kMinute };
163enum class Arithmetic {
kAdd, kSubtract };
166enum class TimePreposition { kSince, kUntil };
170 Isolate* isolate, DirectHandle<Object> options,
Offset fallback,
171 const char* method_name);
186enum class UnsignedRoundingMode {
194enum class MatchBehaviour { kMatchExactly, kMatchMinutes };
197enum class UnitGroup {
203struct DifferenceSettings {
208 DirectHandle<JSReceiver> options;
210enum class DisallowedUnitsInDifferenceSettings {
214Maybe<DifferenceSettings> GetDifferenceSettings(
215 Isolate* isolate, TimePreposition operation, DirectHandle<Object> options,
216 UnitGroup unit_group, DisallowedUnitsInDifferenceSettings disallowed_units,
217 Unit fallback_smallest_unit, Unit smallest_largest_default_unit,
218 const char* method_name);
225 Isolate* isolate, DirectHandle<String> iso_string);
229ParseTemporalDateTimeString(Isolate* isolate, DirectHandle<String> iso_string);
233 Isolate* isolate, DirectHandle<String> iso_string);
236Maybe<TimeRecordWithCalendar> ParseTemporalTimeString(
237 Isolate* isolate, DirectHandle<String> iso_string);
241 Isolate* isolate, DirectHandle<String> iso_string);
245 Isolate* isolate, DirectHandle<String> iso_string);
253 Isolate* isolate, DirectHandle<String> iso_string);
255 Isolate* isolate, DirectHandle<String> iso_string);
257DateRecord BalanceISODate(Isolate* isolate,
const DateRecord&
date);
262 Isolate* isolate, DirectHandle<BigInt> epoch_nanoseconds,
263 const TimeDurationRecord& addend);
268 const TimeDurationRecord& duration,
const char* method_name);
273 const char* method_name);
277 Isolate* isolate, Unit
largest_unit,
const TimeDurationRecord& dur1,
278 const TimeDurationRecord& dur2,
const char* method_name);
281enum BalanceOverflow {
286struct BalancePossiblyInfiniteDurationResult {
287 TimeDurationRecord value;
288 BalanceOverflow overflow;
291BalancePossiblyInfiniteDuration(Isolate* isolate, Unit
largest_unit,
293 const TimeDurationRecord& duration,
294 const char* method_name);
300BalancePossiblyInfiniteDuration(Isolate* isolate, Unit
largest_unit,
303 const char* method_name);
305BalancePossiblyInfiniteDuration(Isolate* isolate, Unit
largest_unit,
307 const char* method_name) {
308 return BalancePossiblyInfiniteDuration(isolate,
largest_unit,
309 isolate->factory()->undefined_value(),
314 Isolate* isolate,
const DateTimeRecord& date_time1,
315 const DateTimeRecord& date_time2, DirectHandle<JSReceiver>
calendar,
317 const char* method_name);
321 Isolate* isolate,
const DateTimeRecord& date_time,
322 DirectHandle<JSReceiver>
calendar,
const DurationRecord& addend,
323 DirectHandle<Object> options);
327 Isolate* isolate, DirectHandle<BigInt> eopch_nanoseconds,
329 const DurationRecord& addend,
const char* method_name);
332 Isolate* isolate, DirectHandle<BigInt> eopch_nanoseconds,
334 const DurationRecord& addend, DirectHandle<Object> options,
335 const char* method_name);
338bool IsValidEpochNanoseconds(Isolate* isolate,
339 DirectHandle<BigInt> epoch_nanoseconds);
341struct NanosecondsToDaysResult {
349 Isolate* isolate, DirectHandle<BigInt>
nanoseconds,
350 DirectHandle<Object> relative_to_obj,
const char* method_name);
353enum class OffsetBehaviour { kOption,
kExact, kWall };
356Maybe<RoundingMode> ToTemporalRoundingMode(Isolate* isolate,
357 DirectHandle<JSReceiver> options,
359 const char* method_name) {
365 isolate, options,
"roundingMode", method_name,
366 {
"ceil",
"floor",
"expand",
"trunc",
"halfCeil",
"halfFloor",
367 "halfExpand",
"halfTrunc",
"halfEven"},
368 {RoundingMode::kCeil, RoundingMode::kFloor, RoundingMode::kExpand,
369 RoundingMode::kTrunc, RoundingMode::kHalfCeil, RoundingMode::kHalfFloor,
370 RoundingMode::kHalfExpand, RoundingMode::kHalfTrunc,
371 RoundingMode::kHalfEven},
376DirectHandle<BigInt> GetEpochFromISOParts(Isolate* isolate,
377 const DateTimeRecord& date_time);
380int32_t ISODaysInMonth(Isolate* isolate, int32_t year, int32_t month);
383int32_t ISODaysInYear(Isolate* isolate, int32_t year);
385bool IsValidTime(Isolate* isolate,
const TimeRecord& time);
388bool IsValidISODate(Isolate* isolate,
const DateRecord&
date);
391int32_t CompareISODate(
const DateRecord& date1,
const DateRecord& date2);
394void BalanceISOYearMonth(Isolate* isolate, int32_t* year, int32_t* month);
398BalanceTime(
const UnbalancedTimeRecord& time);
402 Isolate* isolate,
const TimeRecord& time1,
const TimeRecord& time2);
406 const TimeRecord& time,
407 const TimeDurationRecord& addend);
410DirectHandle<BigInt> TotalDurationNanoseconds(
411 Isolate* isolate,
const TimeDurationRecord& duration,
double offset_shift);
414Maybe<TimeRecord> ToTemporalTimeRecord(
415 Isolate* isolate, DirectHandle<JSReceiver> temporal_time_like,
416 const char* method_name);
421 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
422 DirectHandle<Object>
date, DirectHandle<Object> durations,
423 DirectHandle<Object> options, DirectHandle<Object> date_add);
425 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
426 DirectHandle<Object>
date, DirectHandle<Object> durations,
427 DirectHandle<Object> options);
429 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
430 DirectHandle<Object>
date, DirectHandle<Object> durations);
434 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
435 DirectHandle<Object>
one, DirectHandle<Object> two,
436 DirectHandle<Object> options, DirectHandle<Object> date_until);
439MaybeDirectHandle<FixedArray> CalendarFields(
440 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
441 DirectHandle<FixedArray> field_names);
445 Isolate* isolate, DirectHandle<JSReceiver>
time_zone,
446 DirectHandle<Object> instant,
const char* method_name);
449MaybeDirectHandle<JSReceiver> ToTemporalCalendarWithISODefault(
450 Isolate* isolate, DirectHandle<Object> temporal_calendar_like,
451 const char* method_name);
454bool IsBuiltinCalendar(Isolate* isolate, DirectHandle<String>
id);
457int32_t CalendarIndex(Isolate* isolate, DirectHandle<String>
id);
460bool IsValidTimeZoneName(Isolate* isolate, DirectHandle<String>
time_zone);
463DirectHandle<String> CanonicalizeTimeZoneName(Isolate* isolate,
467MaybeDirectHandle<Number> ToIntegerThrowOnInfinity(
468 Isolate* isolate, DirectHandle<Object> argument);
471MaybeDirectHandle<Number> ToPositiveInteger(Isolate* isolate,
472 DirectHandle<Object> argument);
474inline double modulo(
double a, int32_t b) {
return a - std::floor(a / b) * b; }
476#define STRINGIFY(x) #x
477#define TOSTRING(x) STRINGIFY(x)
478#define AT __FILE__ ":" TOSTRING(__LINE__)
481#define TEMPORAL_DEBUG_INFO AT
482#define TEMPORAL_ENTER_FUNC()
487#define TEMPORAL_DEBUG_INFO AT
488#define TEMPORAL_ENTER_FUNC()
493#define NEW_TEMPORAL_INVALID_ARG_TYPE_ERROR() \
495 MessageTemplate::kInvalidArgumentForTemporal, \
496 isolate->factory()->NewStringFromStaticChars(TEMPORAL_DEBUG_INFO))
498#define NEW_TEMPORAL_INVALID_ARG_RANGE_ERROR() \
500 MessageTemplate::kInvalidTimeValueForTemporal, \
501 isolate->factory()->NewStringFromStaticChars(TEMPORAL_DEBUG_INFO))
504#ifdef V8_INTL_SUPPORT
505DirectHandle<String> DefaultTimeZone(Isolate* isolate) {
510DirectHandle<String> DefaultTimeZone(Isolate* isolate) {
512 return isolate->factory()->UTC_string();
517bool ISODateTimeWithinLimits(Isolate* isolate,
518 const DateTimeRecord& date_time) {
537 if (date_time.date.year > -271821 && date_time.date.year < 275760)
539 if (date_time.date.year < -271821 || date_time.date.year > 275760)
541 if (date_time.date.year == -271821) {
542 if (date_time.date.month > 4)
return true;
543 if (date_time.date.month < 4)
return false;
544 if (date_time.date.day > 19)
return true;
545 if (date_time.date.day < 19)
return false;
546 if (date_time.time.hour > 0)
return true;
547 if (date_time.time.minute > 0)
return true;
548 if (date_time.time.second > 0)
return true;
549 if (date_time.time.millisecond > 0)
return true;
550 if (date_time.time.microsecond > 0)
return true;
551 return date_time.time.nanosecond > 0;
554 if (date_time.date.month > 9)
return false;
555 if (date_time.date.month < 9)
return true;
556 return date_time.date.day < 14;
568bool ISOYearMonthWithinLimits(int32_t year, int32_t month) {
573 if (year < -271821 || year > 275760)
return false;
576 if (year == -271821 && month < 4)
return false;
579 if (year == 275760 && month > 9)
return false;
584#define ORDINARY_CREATE_FROM_CONSTRUCTOR(obj, target, new_target, T) \
585 DirectHandle<JSReceiver> new_target_receiver = Cast<JSReceiver>(new_target); \
586 DirectHandle<Map> map; \
587 ASSIGN_RETURN_ON_EXCEPTION( \
589 JSFunction::GetDerivedMap(isolate, target, new_target_receiver)); \
590 DirectHandle<T> object = \
591 Cast<T>(isolate->factory()->NewFastOrSlowJSObjectFromMap(map));
593#define THROW_INVALID_RANGE(T) \
594 THROW_NEW_ERROR(isolate, NEW_TEMPORAL_INVALID_ARG_RANGE_ERROR());
596#define CONSTRUCTOR(name) \
597 DirectHandle<JSFunction>( \
599 isolate->context()->native_context()->temporal_##name##_function()), \
603DirectHandle<BigInt> SystemUTCEpochNanoseconds(Isolate* isolate) {
613 double ns = ms * 1000000.0;
614 ns = std::floor(std::max(-8.64e21, std::min(ns, 8.64e21)));
620MaybeDirectHandle<JSTemporalCalendar> CreateTemporalCalendar(
621 Isolate* isolate, DirectHandle<JSFunction> target,
634 object->set_flags(0);
636 object->set_calendar_index(index);
641MaybeDirectHandle<JSTemporalCalendar> CreateTemporalCalendar(
642 Isolate* isolate, DirectHandle<String>
identifier) {
649MaybeDirectHandle<JSTemporalPlainDate> CreateTemporalDate(
650 Isolate* isolate, DirectHandle<JSFunction> target,
652 DirectHandle<JSReceiver>
calendar) {
660 if (!IsValidISODate(isolate,
date)) {
665 if (!ISODateTimeWithinLimits(isolate, {
date, {12, 0, 0, 0, 0, 0}})) {
675 object->set_year_month_day(0);
677 object->set_iso_year(
date.year);
679 object->set_iso_month(
date.month);
681 object->set_iso_day(
date.day);
688MaybeDirectHandle<JSTemporalPlainDate> CreateTemporalDate(
689 Isolate* isolate,
const DateRecord&
date,
690 DirectHandle<JSReceiver>
calendar) {
692 return CreateTemporalDate(isolate,
CONSTRUCTOR(plain_date),
698 Isolate* isolate, DirectHandle<JSFunction> target,
699 DirectHandle<HeapObject>
new_target,
const DateTimeRecord& date_time,
700 DirectHandle<JSReceiver>
calendar) {
707 if (!IsValidISODate(isolate, date_time.date)) {
712 if (!IsValidTime(isolate, date_time.time)) {
717 if (!ISODateTimeWithinLimits(isolate, date_time)) {
728 JSTemporalPlainDateTime)
730 object->set_year_month_day(0);
731 object->set_hour_minute_second(0);
732 object->set_second_parts(0);
734 object->set_iso_year(date_time.date.year);
736 object->set_iso_month(date_time.date.month);
738 object->set_iso_day(date_time.date.day);
740 object->set_iso_hour(date_time.time.hour);
742 object->set_iso_minute(date_time.time.minute);
744 object->set_iso_second(date_time.time.second);
746 object->set_iso_millisecond(date_time.time.millisecond);
748 object->set_iso_microsecond(date_time.time.microsecond);
750 object->set_iso_nanosecond(date_time.time.nanosecond);
757MaybeDirectHandle<JSTemporalPlainDateTime> CreateTemporalDateTimeDefaultTarget(
758 Isolate* isolate,
const DateTimeRecord& date_time,
759 DirectHandle<JSReceiver>
calendar) {
773 return CreateTemporalDateTimeDefaultTarget(isolate, date_time,
calendar);
780MaybeDirectHandle<JSTemporalPlainTime> CreateTemporalTime(
781 Isolate* isolate, DirectHandle<JSFunction> target,
782 DirectHandle<HeapObject>
new_target,
const TimeRecord& time) {
786 if (!IsValidTime(isolate, time)) {
790 DirectHandle<JSTemporalCalendar>
calendar =
799 object->set_hour_minute_second(0);
800 object->set_second_parts(0);
802 object->set_iso_hour(time.hour);
804 object->set_iso_minute(time.minute);
806 object->set_iso_second(time.second);
808 object->set_iso_millisecond(time.millisecond);
810 object->set_iso_microsecond(time.microsecond);
812 object->set_iso_nanosecond(time.nanosecond);
820MaybeDirectHandle<JSTemporalPlainTime> CreateTemporalTime(
821 Isolate* isolate,
const TimeRecord& time) {
823 return CreateTemporalTime(isolate,
CONSTRUCTOR(plain_time),
828MaybeDirectHandle<JSTemporalPlainMonthDay> CreateTemporalMonthDay(
829 Isolate* isolate, DirectHandle<JSFunction> target,
830 DirectHandle<HeapObject>
new_target, int32_t iso_month, int32_t iso_day,
831 DirectHandle<JSReceiver>
calendar, int32_t reference_iso_year) {
836 if (!IsValidISODate(isolate, {reference_iso_year, iso_month, iso_day})) {
842 if (!ISODateTimeWithinLimits(
844 {{reference_iso_year, iso_month, iso_day}, {12, 0, 0, 0, 0, 0}})) {
853 JSTemporalPlainMonthDay)
854 object->set_year_month_day(0);
856 object->set_iso_month(iso_month);
858 object->set_iso_day(iso_day);
862 object->set_iso_year(reference_iso_year);
867MaybeDirectHandle<JSTemporalPlainMonthDay> CreateTemporalMonthDay(
868 Isolate* isolate, int32_t iso_month, int32_t iso_day,
869 DirectHandle<JSReceiver>
calendar, int32_t reference_iso_year) {
870 return CreateTemporalMonthDay(isolate,
CONSTRUCTOR(plain_month_day),
872 iso_day,
calendar, reference_iso_year);
876MaybeDirectHandle<JSTemporalPlainYearMonth> CreateTemporalYearMonth(
877 Isolate* isolate, DirectHandle<JSFunction> target,
878 DirectHandle<HeapObject>
new_target, int32_t iso_year, int32_t iso_month,
879 DirectHandle<JSReceiver>
calendar, int32_t reference_iso_day) {
885 if (!IsValidISODate(isolate, {iso_year, iso_month, reference_iso_day})) {
890 if (!ISOYearMonthWithinLimits(iso_year, iso_month)) {
898 JSTemporalPlainYearMonth)
899 object->set_year_month_day(0);
901 object->set_iso_year(iso_year);
903 object->set_iso_month(iso_month);
907 object->set_iso_day(reference_iso_day);
912MaybeDirectHandle<JSTemporalPlainYearMonth> CreateTemporalYearMonth(
913 Isolate* isolate, int32_t iso_year, int32_t iso_month,
914 DirectHandle<JSReceiver>
calendar, int32_t reference_iso_day) {
916 return CreateTemporalYearMonth(isolate,
CONSTRUCTOR(plain_year_month),
918 iso_month,
calendar, reference_iso_day);
922MaybeDirectHandle<JSTemporalZonedDateTime> CreateTemporalZonedDateTime(
923 Isolate* isolate, DirectHandle<JSFunction> target,
924 DirectHandle<HeapObject>
new_target, DirectHandle<BigInt> epoch_nanoseconds,
929 DCHECK(IsValidEpochNanoseconds(isolate, epoch_nanoseconds));
938 JSTemporalZonedDateTime)
940 object->set_nanoseconds(*epoch_nanoseconds);
949MaybeDirectHandle<JSTemporalZonedDateTime> CreateTemporalZonedDateTime(
950 Isolate* isolate, DirectHandle<BigInt> epoch_nanoseconds,
953 return CreateTemporalZonedDateTime(isolate,
CONSTRUCTOR(zoned_date_time),
958inline double NormalizeMinusZero(
double v) {
return IsMinusZero(v) ? 0 : v; }
961Maybe<DateDurationRecord> DateDurationRecord::Create(
965 if (!IsValidDuration(isolate,
969 Nothing<DateDurationRecord>());
982 Isolate* isolate,
double days,
double hours,
double minutes,
double seconds,
983 double milliseconds,
double microseconds,
double nanoseconds) {
989 if (!IsValidDuration(isolate, {0, 0, 0,
record})) {
992 Nothing<TimeDurationRecord>());
1004 double hours,
double minutes,
double seconds,
double milliseconds,
1013 {
days, hours, minutes, seconds, milliseconds, microseconds,
nanoseconds}};
1014 if (!IsValidDuration(isolate,
record)) {
1017 Nothing<DurationRecord>());
1034 Factory* factory = isolate->factory();
1038 if (!IsValidDuration(isolate, duration)) {
1047 const TimeDurationRecord& time_duration = duration.
time_duration;
1048 DirectHandle<Number>
years =
1050 DirectHandle<Number>
months =
1052 DirectHandle<Number>
weeks =
1054 DirectHandle<Number>
days =
1055 factory->
NewNumber(NormalizeMinusZero(time_duration.days));
1056 DirectHandle<Number> hours =
1057 factory->
NewNumber(NormalizeMinusZero(time_duration.hours));
1058 DirectHandle<Number> minutes =
1059 factory->
NewNumber(NormalizeMinusZero(time_duration.minutes));
1060 DirectHandle<Number> seconds =
1061 factory->
NewNumber(NormalizeMinusZero(time_duration.seconds));
1062 DirectHandle<Number> milliseconds =
1063 factory->
NewNumber(NormalizeMinusZero(time_duration.milliseconds));
1064 DirectHandle<Number> microseconds =
1065 factory->
NewNumber(NormalizeMinusZero(time_duration.microseconds));
1067 factory->
NewNumber(NormalizeMinusZero(time_duration.nanoseconds));
1071 object->set_years(*
years);
1073 object->set_months(*
months);
1075 object->set_weeks(*
weeks);
1077 object->set_days(*
days);
1079 object->set_hours(*hours);
1081 object->set_minutes(*minutes);
1083 object->set_seconds(*seconds);
1085 object->set_milliseconds(*milliseconds);
1087 object->set_microseconds(*microseconds);
1094MaybeDirectHandle<JSTemporalDuration> CreateTemporalDuration(
1095 Isolate* isolate,
const DurationRecord& duration) {
1097 return CreateTemporalDuration(isolate,
CONSTRUCTOR(duration),
1113 DCHECK(IsValidEpochNanoseconds(isolate, epoch_nanoseconds));
1121 object->set_nanoseconds(*epoch_nanoseconds);
1136MaybeDirectHandle<JSTemporalTimeZone> CreateTemporalTimeZoneFromIndex(
1137 Isolate* isolate, DirectHandle<JSFunction> target,
1138 DirectHandle<HeapObject>
new_target, int32_t index) {
1142 object->set_flags(0);
1143 object->set_details(0);
1145 object->set_is_offset(
false);
1146 object->set_offset_milliseconds_or_time_zone_index(index);
1150DirectHandle<JSTemporalTimeZone> CreateTemporalTimeZoneUTC(
1151 Isolate* isolate, DirectHandle<JSFunction> target,
1154 return CreateTemporalTimeZoneFromIndex(isolate, target,
new_target, 0)
1158DirectHandle<JSTemporalTimeZone> CreateTemporalTimeZoneUTC(Isolate* isolate) {
1164bool IsUTC(Isolate* isolate, DirectHandle<String>
time_zone);
1168 Isolate* isolate, DirectHandle<JSFunction> target,
1178 Maybe<int64_t> maybe_offset_nanoseconds =
1179 ParseTimeZoneOffsetString(isolate,
identifier);
1181 if (maybe_offset_nanoseconds.IsNothing()) {
1182 DCHECK(isolate->has_exception());
1183 isolate->clear_exception();
1186 CanonicalizeTimeZoneName(isolate,
identifier)));
1191 return CreateTemporalTimeZoneUTC(isolate, target,
new_target);
1193#ifdef V8_INTL_SUPPORT
1196 return CreateTemporalTimeZoneFromIndex(isolate, target,
new_target,
1208 object->set_flags(0);
1209 object->set_details(0);
1211 object->set_is_offset(
true);
1212 object->set_offset_nanoseconds(maybe_offset_nanoseconds.FromJust());
1218MaybeDirectHandle<JSTemporalTimeZone> CreateTemporalTimeZoneDefaultTarget(
1219 Isolate* isolate, DirectHandle<String>
identifier) {
1230 return CreateTemporalTimeZoneDefaultTarget(isolate,
identifier);
1237DirectHandle<JSTemporalInstant> SystemInstant(
Isolate* isolate) {
1240 DirectHandle<BigInt> ns = SystemUTCEpochNanoseconds(isolate);
1246DirectHandle<JSTemporalTimeZone> SystemTimeZone(Isolate* isolate) {
1248 DirectHandle<String> default_time_zone = DefaultTimeZone(isolate);
1253DateTimeRecord GetISOPartsFromEpoch(Isolate* isolate,
1254 DirectHandle<BigInt> epoch_nanoseconds) {
1258 DCHECK(IsValidEpochNanoseconds(isolate, epoch_nanoseconds));
1261 DirectHandle<BigInt> remainder_ns =
1264 if (remainder_ns->IsNegative()) {
1266 BigInt::Add(isolate, remainder_ns, million).ToHandleChecked();
1286 &wday, &
hour, &min, &sec, &ms);
1291 result.date.month = month + 1;
1303 result.time.minute = min;
1307 result.time.second = sec;
1311 result.time.millisecond = ms;
1315 int64_t
remainder = remainder_ns->AsInt64();
1331DateTimeRecord BalanceISODateTime(Isolate* isolate,
1332 const DateTimeRecord& date_time) {
1338 DateTimeRecord balanced_time =
1339 BalanceTime({
static_cast<double>(date_time.time.hour),
1340 static_cast<double>(date_time.time.minute),
1341 static_cast<double>(date_time.time.second),
1342 static_cast<double>(date_time.time.millisecond),
1343 static_cast<double>(date_time.time.microsecond),
1344 static_cast<double>(date_time.time.nanosecond)});
1347 DateRecord added_date = date_time.date;
1348 added_date.day += balanced_time.date.day;
1349 DateRecord balanced_date = BalanceISODate(isolate, added_date);
1356 return {balanced_date, balanced_time.time};
1360double RoundTowardsZero(
double x) {
1364 return -std::floor(std::abs(
x));
1366 return std::floor(std::abs(
x));
1371DirectHandle<String> TemporalDurationToString(Isolate* isolate,
1372 const DurationRecord& duration,
1374 IncrementalStringBuilder builder(isolate);
1378 DurationRecord dur = duration;
1384 double microseconds_add =
1385 RoundTowardsZero(dur.time_duration.nanoseconds / 1000);
1387 dur.time_duration.nanoseconds =
1388 std::fmod(dur.time_duration.nanoseconds, 1000);
1391 double milliseconds_add = RoundTowardsZero(
1392 dur.time_duration.microseconds / 1000 + microseconds_add / 1000);
1394 dur.time_duration.microseconds =
1395 std::fmod(std::fmod(dur.time_duration.microseconds, 1000) +
1396 std::fmod(microseconds_add, 1000),
1399 double seconds_add = RoundTowardsZero(dur.time_duration.milliseconds / 1000 +
1400 milliseconds_add / 1000);
1402 dur.time_duration.milliseconds =
1403 std::fmod(std::fmod(dur.time_duration.milliseconds, 1000) +
1404 std::fmod(milliseconds_add, 1000),
1408 IncrementalStringBuilder date_part(isolate);
1411 base::ScopedVector<char> buf(320);
1414 if (dur.years != 0) {
1417 SNPrintF(buf,
"%.0f", std::abs(dur.years));
1418 date_part.AppendCString(buf.data());
1419 date_part.AppendCharacter(
'Y');
1422 if (dur.months != 0) {
1426 SNPrintF(buf,
"%.0f", std::abs(dur.months));
1427 date_part.AppendCString(buf.data());
1428 date_part.AppendCharacter(
'M');
1431 if (dur.weeks != 0) {
1435 SNPrintF(buf,
"%.0f", std::abs(dur.weeks));
1436 date_part.AppendCString(buf.data());
1437 date_part.AppendCharacter(
'W');
1440 if (dur.time_duration.days != 0) {
1444 SNPrintF(buf,
"%.0f", std::abs(dur.time_duration.days));
1445 date_part.AppendCString(buf.data());
1446 date_part.AppendCharacter(
'D');
1449 IncrementalStringBuilder time_part(isolate);
1451 if (dur.time_duration.hours != 0) {
1454 SNPrintF(buf,
"%.0f", std::abs(dur.time_duration.hours));
1455 time_part.AppendCString(buf.data());
1456 time_part.AppendCharacter(
'H');
1459 if (dur.time_duration.minutes != 0) {
1463 SNPrintF(buf,
"%.0f", std::abs(dur.time_duration.minutes));
1464 time_part.AppendCString(buf.data());
1465 time_part.AppendCharacter(
'M');
1467 IncrementalStringBuilder seconds_part(isolate);
1468 IncrementalStringBuilder decimal_part(isolate);
1472 if ((dur.time_duration.seconds != 0 || seconds_add != 0 ||
1473 dur.time_duration.milliseconds != 0 ||
1474 dur.time_duration.microseconds != 0 ||
1475 dur.time_duration.nanoseconds != 0) ||
1476 (dur.years == 0 && dur.months == 0 && dur.weeks == 0 &&
1477 dur.time_duration.days == 0 && dur.time_duration.hours == 0 &&
1478 dur.time_duration.minutes == 0) ||
1482 int64_t fraction = std::abs(dur.time_duration.milliseconds) * 1e6 +
1483 std::abs(dur.time_duration.microseconds) * 1e3 +
1484 std::abs(dur.time_duration.nanoseconds);
1487 int64_t divisor = 100000000;
1494 while (fraction > 0) {
1495 decimal_part.AppendInt(
static_cast<int32_t>(fraction / divisor));
1496 fraction %= divisor;
1500 }
else if (
precision == Precision::k0) {
1508 for (int32_t len = 0; len < precision_len; len++) {
1509 decimal_part.AppendInt(
static_cast<int32_t>(fraction / divisor));
1510 fraction %= divisor;
1515 if (std::abs(seconds_add + dur.time_duration.seconds) <
kMaxSafeInteger) {
1518 dur.time_duration.seconds += seconds_add;
1519 SNPrintF(buf,
"%.0f", std::abs(dur.time_duration.seconds));
1520 seconds_part.AppendCString(buf.data());
1525 seconds_part.AppendString(
1531 std::abs(seconds_add)))
1534 isolate->factory()->NewNumber(
1535 std::abs(dur.time_duration.seconds)))
1538 .ToHandleChecked());
1542 if (decimal_part.Length() != 0) {
1545 seconds_part.AppendCharacter(
'.');
1546 seconds_part.AppendString(decimal_part.Finish().ToHandleChecked());
1551 time_part.AppendString(seconds_part.Finish().ToHandleChecked());
1552 time_part.AppendCharacter(
'S');
1557 builder.AppendCharacter(
'-');
1562 builder.AppendCharacter(
'P');
1563 builder.AppendString(date_part.Finish().ToHandleChecked());
1566 if (time_part.Length() > 0) {
1569 builder.AppendCharacter(
'T');
1570 builder.AppendString(time_part.Finish().ToHandleChecked());
1572 return builder.Finish().ToHandleChecked();
1575void ToZeroPaddedDecimalString(IncrementalStringBuilder* builder, int32_t n,
1576 int32_t min_length);
1578void FormatSecondsStringPart(IncrementalStringBuilder* builder, int32_t
second,
1589 builder->AppendCharacter(
':');
1590 ToZeroPaddedDecimalString(builder,
second, 2);
1593 int64_t divisor = 100000000;
1597 if (fraction == 0) {
1600 builder->AppendCharacter(
'.');
1604 while (fraction > 0) {
1605 builder->AppendInt(
static_cast<int32_t>(fraction / divisor));
1606 fraction %= divisor;
1615 builder->AppendCharacter(
'.');
1621 for (int32_t len = 0; len < precision_len; len++) {
1622 builder->AppendInt(
static_cast<int32_t>(fraction / divisor));
1623 fraction %= divisor;
1632DirectHandle<String> TemporalTimeToString(Isolate* isolate,
1633 const TimeRecord& time,
1637 IncrementalStringBuilder builder(isolate);
1639 ToZeroPaddedDecimalString(&builder, time.hour, 2);
1640 builder.AppendCharacter(
':');
1642 ToZeroPaddedDecimalString(&builder, time.minute, 2);
1645 FormatSecondsStringPart(&builder, time.second, time.millisecond,
1646 time.microsecond, time.nanosecond,
precision);
1649 return builder.Finish().ToHandleChecked();
1652DirectHandle<String> TemporalTimeToString(
1653 Isolate* isolate, DirectHandle<JSTemporalPlainTime> temporal_time,
1655 return TemporalTimeToString(
1657 {temporal_time->iso_hour(), temporal_time->iso_minute(),
1658 temporal_time->iso_second(), temporal_time->iso_millisecond(),
1659 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()},
1669 const char* method_name) {
1672 int64_t offset_nanoseconds;
1674 isolate, offset_nanoseconds,
1675 GetOffsetNanosecondsFor(isolate,
time_zone, instant, method_name),
1691 result.time.nanosecond += offset_nanoseconds % 1000;
1692 result.time.microsecond += (offset_nanoseconds / 1000) % 1000;
1693 result.time.millisecond += (offset_nanoseconds / 1000000L) % 1000;
1694 result.time.second += (offset_nanoseconds / 1000000000L) % 60;
1695 result.time.minute += (offset_nanoseconds / 60000000000L) % 60;
1696 result.time.hour += (offset_nanoseconds / 3600000000000L) % 24;
1697 result.date.day += (offset_nanoseconds / 86400000000000L);
1704 return temporal::CreateTemporalDateTime(isolate,
result,
calendar);
1713 DirectHandle<Object> date_time) {
1717 DirectHandle<Object> function;
1721 isolate->factory()->getPossibleInstantsFor_string()));
1722 if (!IsCallable(*function)) {
1725 NewTypeError(MessageTemplate::kCalledNonCallable,
1726 isolate->factory()->getPossibleInstantsFor_string()));
1728 DirectHandle<Object> possible_instants;
1730 DirectHandle<Object>
args[] = {date_time};
1732 isolate, possible_instants,
1739 DirectHandle<Object>
args[] = {possible_instants};
1741 isolate, possible_instants,
1743 isolate, isolate->temporal_instant_fixed_array_from_iterable(),
1746 DCHECK(IsFixedArray(*possible_instants));
1752MaybeDirectHandle<JSTemporalInstant> DisambiguatePossibleInstants(
1753 Isolate* isolate, DirectHandle<FixedArray> possible_instants,
1754 DirectHandle<JSReceiver>
time_zone, DirectHandle<Object> date_time_obj,
1755 Disambiguation disambiguation,
const char* method_name) {
1758 DCHECK(IsJSTemporalPlainDateTime(*date_time_obj));
1762 int32_t n = possible_instants->length();
1767 DirectHandle<Object> ret_obj(possible_instants->get(0), isolate);
1768 DCHECK(IsJSTemporalInstant(*ret_obj));
1774 if (disambiguation == Disambiguation::kEarlier ||
1775 disambiguation == Disambiguation::kCompatible) {
1777 DirectHandle<Object> ret_obj(possible_instants->get(0), isolate);
1778 DCHECK(IsJSTemporalInstant(*ret_obj));
1782 if (disambiguation == Disambiguation::kLater) {
1784 DirectHandle<Object> ret_obj(possible_instants->get(n - 1), isolate);
1785 DCHECK(IsJSTemporalInstant(*ret_obj));
1789 DCHECK_EQ(disambiguation, Disambiguation::kReject);
1796 if (disambiguation == Disambiguation::kReject) {
1805 DirectHandle<BigInt> epoch_nanoseconds = GetEpochFromISOParts(
1807 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
1808 {date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(),
1809 date_time->iso_millisecond(), date_time->iso_microsecond(),
1810 date_time->iso_nanosecond()}});
1813 DirectHandle<BigInt> one_day_in_ns =
1815 DirectHandle<BigInt> day_before_ns =
1820 if (!IsValidEpochNanoseconds(isolate, day_before_ns)) {
1824 DirectHandle<JSTemporalInstant> day_before =
1827 DirectHandle<BigInt> day_after_ns =
1828 BigInt::Add(isolate, epoch_nanoseconds, one_day_in_ns).ToHandleChecked();
1831 if (!IsValidEpochNanoseconds(isolate, day_after_ns)) {
1835 DirectHandle<JSTemporalInstant> day_after =
1838 int64_t offset_before;
1840 isolate, offset_before,
1841 GetOffsetNanosecondsFor(isolate,
time_zone, day_before, method_name),
1842 DirectHandle<JSTemporalInstant>());
1844 int64_t offset_after;
1846 isolate, offset_after,
1847 GetOffsetNanosecondsFor(isolate,
time_zone, day_after, method_name),
1848 DirectHandle<JSTemporalInstant>());
1851 double nanoseconds = offset_after - offset_before;
1854 if (disambiguation == Disambiguation::kEarlier) {
1862 DateTimeRecord earlier;
1867 {{date_time->iso_year(), date_time->iso_month(),
1868 date_time->iso_day()},
1869 {date_time->iso_hour(), date_time->iso_minute(),
1870 date_time->iso_second(), date_time->iso_millisecond(),
1871 date_time->iso_microsecond(), date_time->iso_nanosecond()}},
1873 {0, 0, 0, {0, 0, 0, 0, 0, 0, -
nanoseconds}},
1874 isolate->factory()->undefined_value()),
1875 DirectHandle<JSTemporalInstant>());
1881 DirectHandle<JSTemporalPlainDateTime> earlier_date_time;
1883 isolate, earlier_date_time,
1885 isolate, earlier,
direct_handle(date_time->calendar(), isolate)));
1890 isolate, possible_instants,
1894 if (possible_instants->length() == 0) {
1898 DirectHandle<Object> ret_obj(possible_instants->get(0), isolate);
1899 DCHECK(IsJSTemporalInstant(*ret_obj));
1903 DCHECK(disambiguation == Disambiguation::kCompatible ||
1904 disambiguation == Disambiguation::kLater);
1910 DateTimeRecord later;
1913 AddDateTime(isolate,
1914 {{date_time->iso_year(), date_time->iso_month(),
1915 date_time->iso_day()},
1916 {date_time->iso_hour(), date_time->iso_minute(),
1917 date_time->iso_second(), date_time->iso_millisecond(),
1918 date_time->iso_microsecond(), date_time->iso_nanosecond()}},
1920 {0, 0, 0, {0, 0, 0, 0, 0, 0,
nanoseconds}},
1921 isolate->factory()->undefined_value()),
1922 DirectHandle<JSTemporalInstant>());
1930 DirectHandle<JSTemporalPlainDateTime> later_date_time;
1932 isolate, later_date_time,
1934 isolate, later,
direct_handle(date_time->calendar(), isolate)));
1938 isolate, possible_instants,
1941 n = possible_instants->length();
1947 DirectHandle<Object> ret_obj(possible_instants->get(n - 1), isolate);
1948 DCHECK(IsJSTemporalInstant(*ret_obj));
1953MaybeDirectHandle<JSReceiver> GetTemporalCalendarWithISODefault(
1954 Isolate* isolate, DirectHandle<JSReceiver> item,
const char* method_name) {
1957 Factory* factory = isolate->factory();
1963 if (IsJSTemporalPlainDate(*item)) {
1966 if (IsJSTemporalPlainDateTime(*item)) {
1970 if (IsJSTemporalPlainMonthDay(*item)) {
1974 if (IsJSTemporalPlainTime(*item)) {
1977 if (IsJSTemporalPlainYearMonth(*item)) {
1981 if (IsJSTemporalZonedDateTime(*item)) {
1992 return ToTemporalCalendarWithISODefault(isolate,
calendar, method_name);
1995enum class RequiredFields {
2007PrepareTemporalFieldsOrPartial(Isolate* isolate,
2008 DirectHandle<JSReceiver> fields,
2009 DirectHandle<FixedArray> field_names,
2010 RequiredFields required,
bool partial) {
2013 Factory* factory = isolate->factory();
2015 DirectHandle<JSReceiver>
result =
2016 isolate->factory()->NewJSObjectWithNullProto();
2020 int length = field_names->length();
2022 DirectHandle<Object> property_obj(field_names->get(
i), isolate);
2023 DirectHandle<String>
property =
Cast<String>(property_obj);
2025 DirectHandle<Object>
value;
2030 if (IsUndefined(*value)) {
2033 if (partial)
continue;
2036 if (((required == RequiredFields::kDay ||
2037 required == RequiredFields::kYearAndDay) &&
2039 ((required == RequiredFields::kTimeZone ||
2040 required == RequiredFields::kTimeZoneAndOffset) &&
2041 String::Equals(isolate, property, factory->timeZone_string())) ||
2042 (required == RequiredFields::kTimeZoneAndOffset &&
2044 (required == RequiredFields::kYearAndDay &&
2055 String::Equals(isolate, property, factory->millisecond_string()) ||
2056 String::Equals(isolate, property, factory->microsecond_string()) ||
2057 String::Equals(isolate, property, factory->nanosecond_string())) {
2058 value = DirectHandle<Object>(
Smi::zero(), isolate);
2069 if (
String::Equals(isolate, property, factory->month_string()) ||
2072 ToPositiveInteger(isolate, value));
2073 }
else if (
String::Equals(isolate, property, factory->year_string()) ||
2078 factory->millisecond_string()) ||
2080 factory->microsecond_string()) ||
2082 factory->nanosecond_string()) ||
2085 ToIntegerThrowOnInfinity(isolate, value));
2087 factory->monthCode_string()) ||
2115 Isolate* isolate, DirectHandle<JSReceiver> fields,
2116 DirectHandle<FixedArray> field_names, RequiredFields required) {
2119 return PrepareTemporalFieldsOrPartial(isolate, fields, field_names, required,
2125PreparePartialTemporalFields(Isolate* isolate, DirectHandle<JSReceiver> fields,
2126 DirectHandle<FixedArray> field_names) {
2129 return PrepareTemporalFieldsOrPartial(isolate, fields, field_names,
2130 RequiredFields::kNone,
true);
2134template <
typename T>
2135MaybeDirectHandle<T> FromFields(Isolate* isolate,
2137 DirectHandle<JSReceiver> fields,
2138 DirectHandle<Object> options,
2139 DirectHandle<String> property,
2141 DirectHandle<Object> function;
2144 if (!IsCallable(*function)) {
2146 isolate, NewTypeError(MessageTemplate::kCalledNonCallable, property));
2148 DirectHandle<Object>
args[] = {fields, options};
2149 DirectHandle<Object>
result;
2161MaybeDirectHandle<JSTemporalPlainDate> DateFromFields(
2162 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
2163 DirectHandle<JSReceiver> fields, DirectHandle<Object> options) {
2164 return FromFields<JSTemporalPlainDate>(
2165 isolate,
calendar, fields, options,
2166 isolate->factory()->dateFromFields_string(), JS_TEMPORAL_PLAIN_DATE_TYPE);
2170MaybeDirectHandle<JSTemporalPlainYearMonth> YearMonthFromFields(
2171 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
2172 DirectHandle<JSReceiver> fields, DirectHandle<Object> options) {
2173 return FromFields<JSTemporalPlainYearMonth>(
2174 isolate,
calendar, fields, options,
2175 isolate->factory()->yearMonthFromFields_string(),
2176 JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE);
2178MaybeDirectHandle<JSTemporalPlainYearMonth> YearMonthFromFields(
2179 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
2180 DirectHandle<JSReceiver> fields) {
2182 return YearMonthFromFields(isolate,
calendar, fields,
2183 isolate->factory()->undefined_value());
2187MaybeDirectHandle<JSTemporalPlainMonthDay> MonthDayFromFields(
2188 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
2189 DirectHandle<JSReceiver> fields, DirectHandle<Object> options) {
2190 return FromFields<JSTemporalPlainMonthDay>(
2191 isolate,
calendar, fields, options,
2192 isolate->factory()->monthDayFromFields_string(),
2193 JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE);
2195MaybeDirectHandle<JSTemporalPlainMonthDay> MonthDayFromFields(
2196 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
2197 DirectHandle<JSReceiver> fields) {
2199 return MonthDayFromFields(isolate,
calendar, fields,
2200 isolate->factory()->undefined_value());
2204Maybe<ShowOverflow> ToTemporalOverflow(Isolate* isolate,
2205 DirectHandle<Object> options,
2206 const char* method_name) {
2208 if (IsUndefined(*options))
return Just(ShowOverflow::kConstrain);
2209 DCHECK(IsJSReceiver(*options));
2214 {
"constrain",
"reject"},
2215 {ShowOverflow::kConstrain, ShowOverflow::kReject},
2216 ShowOverflow::kConstrain);
2220Maybe<Offset> ToTemporalOffset(Isolate* isolate, DirectHandle<Object> options,
2221 Offset fallback,
const char* method_name) {
2223 if (IsUndefined(*options))
return Just(fallback);
2224 DCHECK(IsJSReceiver(*options));
2230 {
"prefer",
"use",
"ignore",
"reject"},
2231 {Offset::kPrefer, Offset::kUse, Offset::kIgnore, Offset::kReject},
2236Maybe<Disambiguation> ToTemporalDisambiguation(Isolate* isolate,
2237 DirectHandle<Object> options,
2238 const char* method_name) {
2240 if (IsUndefined(*options))
return Just(Disambiguation::kCompatible);
2241 DCHECK(IsJSReceiver(*options));
2246 {
"compatible",
"earlier",
"later",
"reject"},
2247 {Disambiguation::kCompatible, Disambiguation::kEarlier,
2248 Disambiguation::kLater, Disambiguation::kReject},
2249 Disambiguation::kCompatible);
2253MaybeDirectHandle<JSTemporalInstant> BuiltinTimeZoneGetInstantFor(
2254 Isolate* isolate, DirectHandle<JSReceiver>
time_zone,
2255 DirectHandle<JSTemporalPlainDateTime> date_time,
2256 Disambiguation disambiguation,
const char* method_name) {
2260 DirectHandle<FixedArray> possible_instants;
2262 isolate, possible_instants,
2266 return DisambiguatePossibleInstants(isolate, possible_instants,
time_zone,
2267 date_time, disambiguation, method_name);
2271MaybeDirectHandle<JSTemporalInstant> ToTemporalInstant(
2272 Isolate* isolate, DirectHandle<Object> item,
const char* method_name) {
2277 if (IsJSTemporalInstant(*item)) {
2282 if (IsJSTemporalZonedDateTime(*item)) {
2290 DirectHandle<String>
string;
2294 DirectHandle<BigInt> epoch_nanoseconds;
2296 ParseTemporalInstant(isolate,
string));
2308 const char* method_name) {
2309 Factory* factory = isolate->factory();
2311 if (IsJSReceiver(*temporal_calendar_like)) {
2318#define EXTRACT_CALENDAR(T, obj) \
2319 if (IsJSTemporal##T(*obj)) { \
2320 return direct_handle(Cast<JSTemporal##T>(obj)->calendar(), isolate); \
2330#undef EXTRACT_CALENDAR
2338 JSReceiver::HasProperty(isolate, obj, factory->calendar_string()),
2345 isolate, temporal_calendar_like,
2346 JSReceiver::GetProperty(isolate, obj, factory->calendar_string()));
2348 if (IsJSReceiver(*temporal_calendar_like)) {
2349 obj = Cast<JSReceiver>(temporal_calendar_like);
2353 JSReceiver::HasProperty(isolate, obj, factory->calendar_string()),
2365 Object::ToString(isolate, temporal_calendar_like));
2368 ParseTemporalCalendarString(isolate,
identifier));
2371 if (!IsBuiltinCalendar(isolate,
identifier)) {
2373 isolate, NewRangeError(MessageTemplate::kInvalidCalendar,
identifier));
2376 return CreateTemporalCalendar(isolate,
identifier);
2383MaybeDirectHandle<JSReceiver> ToTemporalCalendarWithISODefault(
2384 Isolate* isolate, DirectHandle<Object> temporal_calendar_like,
2385 const char* method_name) {
2389 if (IsUndefined(*temporal_calendar_like)) {
2400DirectHandle<FixedArray> All10UnitsInFixedArray(Isolate* isolate) {
2401 DirectHandle<FixedArray> field_names = isolate->factory()->NewFixedArray(10);
2402 field_names->set(0, ReadOnlyRoots(isolate).day_string());
2403 field_names->set(1, ReadOnlyRoots(isolate).hour_string());
2404 field_names->set(2, ReadOnlyRoots(isolate).microsecond_string());
2405 field_names->set(3, ReadOnlyRoots(isolate).millisecond_string());
2406 field_names->set(4, ReadOnlyRoots(isolate).minute_string());
2407 field_names->set(5, ReadOnlyRoots(isolate).month_string());
2408 field_names->set(6, ReadOnlyRoots(isolate).monthCode_string());
2409 field_names->set(7, ReadOnlyRoots(isolate).nanosecond_string());
2410 field_names->set(8, ReadOnlyRoots(isolate).second_string());
2411 field_names->set(9, ReadOnlyRoots(isolate).year_string());
2416DirectHandle<FixedArray> DayMonthMonthCodeYearInFixedArray(Isolate* isolate) {
2417 DirectHandle<FixedArray> field_names = isolate->factory()->NewFixedArray(4);
2418 field_names->set(0, ReadOnlyRoots(isolate).day_string());
2419 field_names->set(1, ReadOnlyRoots(isolate).month_string());
2420 field_names->set(2, ReadOnlyRoots(isolate).monthCode_string());
2421 field_names->set(3, ReadOnlyRoots(isolate).year_string());
2426DirectHandle<FixedArray> MonthMonthCodeYearInFixedArray(Isolate* isolate) {
2427 DirectHandle<FixedArray> field_names = isolate->factory()->NewFixedArray(3);
2428 field_names->set(0, ReadOnlyRoots(isolate).month_string());
2429 field_names->set(1, ReadOnlyRoots(isolate).monthCode_string());
2430 field_names->set(2, ReadOnlyRoots(isolate).year_string());
2435DirectHandle<FixedArray> MonthCodeYearInFixedArray(Isolate* isolate) {
2436 DirectHandle<FixedArray> field_names = isolate->factory()->NewFixedArray(2);
2437 field_names->set(0, ReadOnlyRoots(isolate).monthCode_string());
2438 field_names->set(1, ReadOnlyRoots(isolate).year_string());
2443MaybeDirectHandle<JSTemporalPlainDate> ToTemporalDate(
2444 Isolate* isolate, DirectHandle<Object> item_obj,
2445 DirectHandle<Object> options,
const char* method_name) {
2449 DCHECK(IsJSReceiver(*options) || IsUndefined(*options));
2451 if (IsJSReceiver(*item_obj)) {
2455 if (IsJSTemporalPlainDate(*item)) {
2460 if (IsJSTemporalZonedDateTime(*item)) {
2463 isolate, ToTemporalOverflow(isolate, options, method_name),
2464 DirectHandle<JSTemporalPlainDate>());
2468 DirectHandle<JSTemporalInstant> instant =
2470 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
2475 DirectHandle<JSTemporalPlainDateTime> plain_date_time;
2477 isolate, plain_date_time,
2480 DirectHandle<JSReceiver>(zoned_date_time->time_zone(), isolate),
2482 DirectHandle<JSReceiver>(zoned_date_time->calendar(), isolate),
2487 return CreateTemporalDate(
2489 {plain_date_time->iso_year(), plain_date_time->iso_month(),
2490 plain_date_time->iso_day()},
2497 if (IsJSTemporalPlainDateTime(*item)) {
2500 isolate, ToTemporalOverflow(isolate, options, method_name),
2501 DirectHandle<JSTemporalPlainDate>());
2504 return CreateTemporalDate(isolate,
2505 {date_time->iso_year(), date_time->iso_month(),
2506 date_time->iso_day()},
2515 GetTemporalCalendarWithISODefault(isolate, item, method_name));
2518 DirectHandle<FixedArray> field_names =
2519 DayMonthMonthCodeYearInFixedArray(isolate);
2521 CalendarFields(isolate,
calendar, field_names));
2524 DirectHandle<JSReceiver> fields;
2526 PrepareTemporalFields(isolate, item, field_names,
2527 RequiredFields::kNone));
2529 return DateFromFields(isolate,
calendar, fields, options);
2533 isolate, ToTemporalOverflow(isolate, options, method_name),
2534 DirectHandle<JSTemporalPlainDate>());
2537 DirectHandle<String>
string;
2541 DateRecordWithCalendar
result;
2543 isolate,
result, ParseTemporalDateString(isolate,
string),
2544 DirectHandle<JSTemporalPlainDate>());
2553 ToTemporalCalendarWithISODefault(isolate,
result.calendar, method_name));
2559MaybeDirectHandle<JSTemporalPlainDate> ToTemporalDate(
2560 Isolate* isolate, DirectHandle<Object> item_obj,
const char* method_name) {
2562 return ToTemporalDate(isolate, item_obj,
2563 isolate->factory()->undefined_value(), method_name);
2567bool IsIntegralNumber(Isolate* isolate, DirectHandle<Object> argument) {
2569 if (!
IsNumber(*argument))
return false;
2572 if (!std::isfinite(number))
return false;
2574 if (std::floor(std::abs(number)) != std::abs(number))
return false;
2580Maybe<double> ToIntegerWithoutRounding(Isolate* isolate,
2581 DirectHandle<Object> argument) {
2583 DirectHandle<Number> number;
2588 return Just(
static_cast<double>(0));
2591 if (!IsIntegralNumber(isolate, number)) {
2605 ShowOverflow overflow) {
2612 case ShowOverflow::kConstrain: {
2618 result.minute = std::max(std::min(
result.minute, 59), 0);
2619 result.second = std::max(std::min(
result.second, 59), 0);
2620 result.millisecond = std::max(std::min(
result.millisecond, 999), 0);
2621 result.microsecond = std::max(std::min(
result.microsecond, 999), 0);
2622 result.nanosecond = std::max(std::min(
result.nanosecond, 999), 0);
2625 case ShowOverflow::kReject:
2629 if (!IsValidTime(isolate, time)) {
2632 Nothing<TimeRecord>());
2644 ShowOverflow overflow = ShowOverflow::kConstrain) {
2645 Factory* factory = isolate->factory();
2646 TimeRecordWithCalendar
result;
2649 if (IsJSReceiver(*item_obj)) {
2653 if (IsJSTemporalPlainTime(*item)) {
2654 return Cast<JSTemporalPlainTime>(item);
2658 if (IsJSTemporalZonedDateTime(*item)) {
2660 auto zoned_date_time = Cast<JSTemporalZonedDateTime>(item);
2663 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
2670 isolate, plain_date_time,
2682 return CreateTemporalTime(isolate, {plain_date_time->iso_hour(),
2683 plain_date_time->iso_minute(),
2684 plain_date_time->iso_second(),
2685 plain_date_time->iso_millisecond(),
2686 plain_date_time->iso_microsecond(),
2687 plain_date_time->iso_nanosecond()})
2691 if (IsJSTemporalPlainDateTime(*item)) {
2695 auto date_time = Cast<JSTemporalPlainDateTime>(item);
2696 return CreateTemporalTime(
2698 {date_time->iso_hour(), date_time->iso_minute(),
2699 date_time->iso_second(), date_time->iso_millisecond(),
2700 date_time->iso_microsecond(), date_time->iso_nanosecond()})
2707 GetTemporalCalendarWithISODefault(isolate, item, method_name));
2711 Object::ToString(isolate,
calendar));
2712 if (!String::Equals(isolate, factory->iso8601_string(),
identifier)) {
2718 isolate,
result.time, ToTemporalTimeRecord(isolate, item, method_name),
2731 Object::ToString(isolate, item_obj));
2734 isolate,
result, ParseTemporalTimeString(isolate,
string),
2742 if (!IsUndefined(*
result.calendar) &&
2743 !String::Equals(isolate, Cast<String>(
result.calendar),
2744 isolate->factory()->iso8601_string())) {
2752 return CreateTemporalTime(isolate,
result.time);
2766 Factory* factory = isolate->factory();
2767 std::array<std::pair<DirectHandle<String>,
double*>, 10> table8 = {
2768 {{factory->days_string(), &
record->time_duration.days},
2769 {factory->hours_string(), &
record->time_duration.hours},
2770 {factory->microseconds_string(), &
record->time_duration.microseconds},
2771 {factory->milliseconds_string(), &
record->time_duration.milliseconds},
2772 {factory->minutes_string(), &
record->time_duration.minutes},
2773 {factory->months_string(), &
record->months},
2774 {factory->nanoseconds_string(), &
record->time_duration.nanoseconds},
2775 {factory->seconds_string(), &
record->time_duration.seconds},
2776 {factory->weeks_string(), &
record->weeks},
2777 {factory->years_string(), &
record->years}}};
2782 for (
const auto& row : table8) {
2789 RowFunction(isolate, temporal_duration_like, row.first, row.second),
2799 const char* method_name) {
2803 if (!IsJSReceiver(*temporal_duration_like_obj)) {
2807 isolate,
string, Object::ToString(isolate, temporal_duration_like_obj),
2808 Nothing<DurationRecord>());
2810 return ParseTemporalDurationString(isolate,
string);
2813 Cast<JSReceiver>(temporal_duration_like_obj);
2816 if (IsJSTemporalDuration(*temporal_duration_like)) {
2824 auto duration = Cast<JSTemporalDuration>(temporal_duration_like);
2825 return DurationRecord::Create(isolate,
2826 Object::NumberValue(duration->years()),
2827 Object::NumberValue(duration->months()),
2828 Object::NumberValue(duration->weeks()),
2829 Object::NumberValue(duration->days()),
2830 Object::NumberValue(duration->hours()),
2831 Object::NumberValue(duration->minutes()),
2832 Object::NumberValue(duration->seconds()),
2833 Object::NumberValue(duration->milliseconds()),
2834 Object::NumberValue(duration->microseconds()),
2835 Object::NumberValue(duration->nanoseconds()));
2847 isolate, temporal_duration_like,
2850 bool not_undefined =
false;
2856 JSReceiver::GetProperty(isolate, temporal_duration_like, prop),
2859 if (IsUndefined(*val)) {
2866 not_undefined =
true;
2871 isolate, *field, ToIntegerWithoutRounding(isolate, val),
2874 return Just(not_undefined);
2877 Nothing<DurationRecord>());
2883 Nothing<DurationRecord>());
2889 if (!IsValidDuration(isolate,
result)) {
2893 Nothing<DurationRecord>());
2907 if (IsJSTemporalDuration(*item)) {
2909 return Cast<JSTemporalDuration>(item);
2920 return CreateTemporalDuration(isolate,
result);
2926 const char* method_name) {
2929 Factory* factory = isolate->factory();
2931 if (IsJSReceiver(*temporal_time_zone_like)) {
2934 if (IsJSTemporalZonedDateTime(*temporal_time_zone_like)) {
2936 auto zoned_date_time =
2937 Cast<JSTemporalZonedDateTime>(temporal_time_zone_like);
2938 return direct_handle(zoned_date_time->time_zone(), isolate);
2945 JSReceiver::HasProperty(isolate, obj, factory->timeZone_string()),
2954 isolate, temporal_time_zone_like,
2955 JSReceiver::GetProperty(isolate, obj, factory->timeZone_string()));
2957 if (IsJSReceiver(*temporal_time_zone_like)) {
2959 obj = Cast<JSReceiver>(temporal_time_zone_like);
2962 JSReceiver::HasProperty(isolate, obj, factory->timeZone_string()),
2973 isolate,
identifier, Object::ToString(isolate, temporal_time_zone_like));
2976 TimeZoneRecord parse_result;
2978 isolate, parse_result, ParseTemporalTimeZoneString(isolate,
identifier),
2982 if (!IsUndefined(*parse_result.name)) {
2983 DCHECK(IsString(*parse_result.name));
2988 std::optional<ParsedISO8601Result> parsed_offset =
2989 TemporalParser::ParseTimeZoneNumericUTCOffset(isolate, name);
2990 if (!parsed_offset.has_value()) {
2993 if (!IsValidTimeZoneName(isolate, name)) {
2997 name = CanonicalizeTimeZoneName(isolate, name);
3000 return temporal::CreateTemporalTimeZone(isolate, name);
3003 if (parse_result.z) {
3004 return CreateTemporalTimeZoneUTC(isolate);
3007 DCHECK(IsString(*parse_result.offset_string));
3008 return temporal::CreateTemporalTimeZone(
3009 isolate, Cast<String>(parse_result.offset_string));
3016MaybeDirectHandle<JSTemporalPlainDateTime> SystemDateTime(
3017 Isolate* isolate, DirectHandle<Object> temporal_time_zone_like,
3018 DirectHandle<Object> calendar_like,
const char* method_name) {
3023 if (IsUndefined(*temporal_time_zone_like)) {
3040 DirectHandle<JSTemporalInstant> instant = SystemInstant(isolate);
3047MaybeDirectHandle<JSTemporalZonedDateTime> SystemZonedDateTime(
3048 Isolate* isolate, DirectHandle<Object> temporal_time_zone_like,
3049 DirectHandle<Object> calendar_like,
const char* method_name) {
3054 if (IsUndefined(*temporal_time_zone_like)) {
3071 DirectHandle<BigInt> ns = SystemUTCEpochNanoseconds(isolate);
3078 return static_cast<int>(
r);
3082DirectHandle<String> FormatTimeZoneOffsetString(Isolate* isolate,
3083 int64_t offset_nanoseconds) {
3084 IncrementalStringBuilder builder(isolate);
3087 builder.AppendCharacter((offset_nanoseconds >= 0) ?
'+' :
'-');
3089 offset_nanoseconds = std::abs(offset_nanoseconds);
3091 int64_t
nanoseconds = offset_nanoseconds % 1000000000;
3093 int32_t seconds = (offset_nanoseconds / 1000000000) % 60;
3095 int32_t minutes = (offset_nanoseconds / 60000000000) % 60;
3097 int32_t hours = offset_nanoseconds / 3600000000000;
3099 ToZeroPaddedDecimalString(&builder, hours, 2);
3102 builder.AppendCharacter(
':');
3103 ToZeroPaddedDecimalString(&builder, minutes, 2);
3113 builder.AppendCharacter(
':');
3114 ToZeroPaddedDecimalString(&builder, seconds, 2);
3115 builder.AppendCharacter(
'.');
3116 int64_t divisor = 100000000;
3118 builder.AppendInt(
static_cast<int>(
nanoseconds / divisor));
3123 }
else if (seconds != 0) {
3126 builder.AppendCharacter(
':');
3127 ToZeroPaddedDecimalString(&builder, seconds, 2);
3131 return builder.Finish().ToHandleChecked();
3134double RoundNumberToIncrement(Isolate* isolate,
double x,
double increment,
3138DirectHandle<String> FormatISOTimeZoneOffsetString(Isolate* isolate,
3139 int64_t offset_nanoseconds) {
3140 IncrementalStringBuilder builder(isolate);
3144 offset_nanoseconds = RoundNumberToIncrement(
3145 isolate, offset_nanoseconds, 60000000000, RoundingMode::kHalfExpand);
3147 builder.AppendCharacter((offset_nanoseconds >= 0) ?
'+' :
'-');
3149 offset_nanoseconds = std::abs(offset_nanoseconds);
3151 int32_t minutes = (offset_nanoseconds / 60000000000) % 60;
3153 int32_t hours = offset_nanoseconds / 3600000000000;
3155 ToZeroPaddedDecimalString(&builder, hours, 2);
3158 builder.AppendCharacter(
':');
3159 ToZeroPaddedDecimalString(&builder, minutes, 2);
3162 return builder.Finish().ToHandleChecked();
3165int32_t DecimalLength(int32_t n) {
3175void ToZeroPaddedDecimalString(IncrementalStringBuilder* builder, int32_t n,
3176 int32_t min_length) {
3177 for (int32_t pad = min_length - DecimalLength(n); pad > 0; pad--) {
3178 builder->AppendCharacter(
'0');
3180 builder->AppendInt(n);
3184void PadISOYear(IncrementalStringBuilder* builder, int32_t
y) {
3187 if (
y >= 0 &&
y <= 9999) {
3189 ToZeroPaddedDecimalString(builder,
y, 4);
3194 builder->AppendCharacter(
'+');
3196 builder->AppendCharacter(
'-');
3199 ToZeroPaddedDecimalString(builder, std::abs(
y), 6);
3204DirectHandle<String> FormatCalendarAnnotation(Isolate* isolate,
3205 DirectHandle<String>
id,
3206 ShowCalendar show_calendar) {
3209 if (show_calendar == ShowCalendar::kNever) {
3210 return isolate->factory()->empty_string();
3213 if (show_calendar == ShowCalendar::kAuto &&
3214 String::Equals(isolate,
id, isolate->factory()->iso8601_string())) {
3215 return isolate->factory()->empty_string();
3218 IncrementalStringBuilder builder(isolate);
3219 builder.AppendCStringLiteral(
"[u-ca=");
3220 builder.AppendString(
id);
3221 builder.AppendCharacter(
']');
3222 return builder.Finish().ToHandleChecked();
3226MaybeDirectHandle<String> MaybeFormatCalendarAnnotation(
3227 Isolate* isolate, DirectHandle<JSReceiver> calendar_object,
3228 ShowCalendar show_calendar) {
3230 if (show_calendar == ShowCalendar::kNever) {
3231 return isolate->factory()->empty_string();
3234 DirectHandle<String> calendar_id;
3238 return FormatCalendarAnnotation(isolate, calendar_id, show_calendar);
3242MaybeDirectHandle<String> TemporalDateToString(
3243 Isolate* isolate, DirectHandle<JSTemporalPlainDate> temporal_date,
3244 ShowCalendar show_calendar) {
3245 IncrementalStringBuilder builder(isolate);
3249 PadISOYear(&builder, temporal_date->iso_year());
3251 builder.AppendCharacter(
'-');
3252 ToZeroPaddedDecimalString(&builder, temporal_date->iso_month(), 2);
3254 builder.AppendCharacter(
'-');
3255 ToZeroPaddedDecimalString(&builder, temporal_date->iso_day(), 2);
3261 MaybeFormatCalendarAnnotation(
3269 return builder.Finish().ToHandleChecked();
3273MaybeDirectHandle<String> TemporalMonthDayToString(
3274 Isolate* isolate, DirectHandle<JSTemporalPlainMonthDay> month_day,
3275 ShowCalendar show_calendar) {
3278 IncrementalStringBuilder builder(isolate);
3280 DirectHandle<String> calendar_id;
3282 isolate, calendar_id,
3285 if (show_calendar == ShowCalendar::kAlways ||
3287 isolate->factory()->iso8601_string())) {
3289 PadISOYear(&builder, month_day->iso_year());
3292 builder.AppendCharacter(
'-');
3295 ToZeroPaddedDecimalString(&builder, month_day->iso_month(), 2);
3298 builder.AppendCharacter(
'-');
3300 ToZeroPaddedDecimalString(&builder, month_day->iso_day(), 2);
3303 DirectHandle<String> calendar_string =
3304 FormatCalendarAnnotation(isolate, calendar_id, show_calendar);
3306 builder.AppendString(calendar_string);
3308 return builder.Finish().ToHandleChecked();
3312MaybeDirectHandle<String> TemporalYearMonthToString(
3313 Isolate* isolate, DirectHandle<JSTemporalPlainYearMonth> year_month,
3314 ShowCalendar show_calendar) {
3317 IncrementalStringBuilder builder(isolate);
3319 PadISOYear(&builder, year_month->iso_year());
3323 builder.AppendCharacter(
'-');
3324 ToZeroPaddedDecimalString(&builder, year_month->iso_month(), 2);
3326 DirectHandle<String> calendar_id;
3328 isolate, calendar_id,
3331 if (show_calendar == ShowCalendar::kAlways ||
3333 isolate->factory()->iso8601_string())) {
3337 builder.AppendCharacter(
'-');
3338 ToZeroPaddedDecimalString(&builder, year_month->iso_day(), 2);
3342 DirectHandle<String> calendar_string =
3343 FormatCalendarAnnotation(isolate, calendar_id, show_calendar);
3345 builder.AppendString(calendar_string);
3347 return builder.Finish().ToHandleChecked();
3351MaybeDirectHandle<String> BuiltinTimeZoneGetOffsetStringFor(
3352 Isolate* isolate, DirectHandle<JSReceiver>
time_zone,
3353 DirectHandle<JSTemporalInstant> instant,
const char* method_name) {
3356 int64_t offset_nanoseconds;
3358 isolate, offset_nanoseconds,
3359 GetOffsetNanosecondsFor(isolate,
time_zone, instant, method_name),
3360 DirectHandle<String>());
3363 return FormatTimeZoneOffsetString(isolate, offset_nanoseconds);
3367Maybe<DateTimeRecordWithCalendar> ParseISODateTime(
3368 Isolate* isolate, DirectHandle<String> iso_string,
3369 const ParsedISO8601Result& parsed);
3376Maybe<DateTimeRecordWithCalendar> ParseISODateTime(
3377 Isolate* isolate, DirectHandle<String> iso_string) {
3384 std::optional<ParsedISO8601Result> parsed;
3386 TemporalParser::ParseTemporalDateTimeString(isolate, iso_string))
3388 (parsed = TemporalParser::ParseTemporalInstantString(isolate, iso_string))
3391 TemporalParser::ParseTemporalMonthDayString(isolate, iso_string))
3393 (parsed = TemporalParser::ParseTemporalTimeString(isolate, iso_string))
3396 TemporalParser::ParseTemporalYearMonthString(isolate, iso_string))
3398 (parsed = TemporalParser::ParseTemporalZonedDateTimeString(isolate,
3401 return ParseISODateTime(isolate, iso_string, *parsed);
3409Maybe<DateTimeRecordWithCalendar> ParseISODateTime(
3410 Isolate* isolate, DirectHandle<String> iso_string,
3411 const ParsedISO8601Result& parsed) {
3414 DateTimeRecordWithCalendar
result;
3416 result.date.year = parsed.date_year;
3418 if (parsed.date_month_is_undefined()) {
3424 result.date.month = parsed.date_month;
3428 if (parsed.date_day_is_undefined()) {
3434 result.date.day = parsed.date_day;
3437 result.time.hour = parsed.time_hour_is_undefined() ? 0 : parsed.time_hour;
3440 parsed.time_minute_is_undefined() ? 0 : parsed.time_minute;
3443 parsed.time_second_is_undefined() ? 0 : parsed.time_second;
3445 if (
result.time.second == 60) {
3450 if (!parsed.time_nanosecond_is_undefined()) {
3466 result.time.millisecond = parsed.time_nanosecond / 1000000;
3468 result.time.microsecond = (parsed.time_nanosecond / 1000) % 1000;
3470 result.time.nanosecond = (parsed.time_nanosecond % 1000);
3474 result.time.millisecond = 0;
3476 result.time.microsecond = 0;
3478 result.time.nanosecond = 0;
3482 if (!IsValidISODate(isolate,
result.date)) {
3489 if (!IsValidTime(isolate,
result.time)) {
3497 result.time_zone = {
false, isolate->factory()->undefined_value(),
3498 isolate->factory()->undefined_value()};
3500 if (parsed.tzi_name_length != 0) {
3505 result.time_zone.name = isolate->factory()->NewSubString(
3506 iso_string, parsed.tzi_name_start,
3507 parsed.tzi_name_start + parsed.tzi_name_length);
3510 if (parsed.utc_designator) {
3512 result.time_zone.z =
true;
3516 if (parsed.offset_string_length != 0) {
3520 result.time_zone.offset_string = isolate->factory()->NewSubString(
3521 iso_string, parsed.offset_string_start,
3522 parsed.offset_string_start + parsed.offset_string_length);
3527 if (parsed.calendar_name_length == 0) {
3529 result.calendar = isolate->factory()->undefined_value();
3533 result.calendar = isolate->factory()->NewSubString(
3534 iso_string, parsed.calendar_name_start,
3535 parsed.calendar_name_start + parsed.calendar_name_length);
3546Maybe<DateRecordWithCalendar> ParseTemporalDateString(
3547 Isolate* isolate, DirectHandle<String> iso_string) {
3553 DateTimeRecordWithCalendar
record;
3555 isolate,
record, ParseTemporalDateTimeString(isolate, iso_string),
3562Maybe<TimeRecordWithCalendar> ParseTemporalTimeString(
3563 Isolate* isolate, DirectHandle<String> iso_string) {
3569 std::optional<ParsedISO8601Result> parsed =
3570 TemporalParser::ParseTemporalTimeString(isolate, iso_string);
3571 if (!parsed.has_value()) {
3579 if (parsed->utc_designator) {
3587 DateTimeRecordWithCalendar
result;
3589 isolate,
result, ParseISODateTime(isolate, iso_string, *parsed),
3595 TimeRecordWithCalendar ret = {
result.time,
result.calendar};
3600Maybe<InstantRecord> ParseTemporalInstantString(
3601 Isolate* isolate, DirectHandle<String> iso_string) {
3606 std::optional<ParsedISO8601Result> parsed =
3607 TemporalParser::ParseTemporalInstantString(isolate, iso_string);
3608 if (!parsed.has_value()) {
3615 DateTimeRecordWithCalendar
result;
3617 isolate,
result, ParseISODateTime(isolate, iso_string, *parsed),
3624 if (
result.time_zone.z) {
3626 offset_string = isolate->factory()->NewStringFromStaticChars(
"+00:00");
3644Maybe<DateTimeRecordWithCalendar> ParseTemporalRelativeToString(
3645 Isolate* isolate, DirectHandle<String> iso_string) {
3650 std::optional<ParsedISO8601Result> parsed =
3651 TemporalParser::ParseTemporalDateTimeString(isolate, iso_string);
3652 if (!parsed.has_value()) {
3659 return ParseISODateTime(isolate, iso_string, *parsed);
3663MaybeDirectHandle<BigInt> ParseTemporalInstant(
3664 Isolate* isolate, DirectHandle<String> iso_string) {
3671 isolate,
result, ParseTemporalInstantString(isolate, iso_string),
3672 DirectHandle<BigInt>());
3681 DirectHandle<BigInt> utc =
3682 GetEpochFromISOParts(isolate, {
result.date,
result.time});
3685 int64_t offset_nanoseconds;
3688 isolate, offset_nanoseconds,
3690 DirectHandle<BigInt>());
3693 DirectHandle<BigInt> result_value =
3698 if (!IsValidEpochNanoseconds(isolate, result_value)) {
3703 return result_value;
3707Maybe<DateTimeRecordWithCalendar> ParseTemporalZonedDateTimeString(
3708 Isolate* isolate, DirectHandle<String> iso_string) {
3712 std::optional<ParsedISO8601Result> parsed =
3713 TemporalParser::ParseTemporalZonedDateTimeString(isolate, iso_string);
3714 if (!parsed.has_value()) {
3721 return ParseISODateTime(isolate, iso_string, *parsed);
3725Maybe<DurationRecord> CreateDurationRecord(Isolate* isolate,
3726 const DurationRecord& duration) {
3730 if (!IsValidDuration(isolate, duration)) {
3740 return Just(duration);
3743inline double IfEmptyReturnZero(
double value) {
3748Maybe<DurationRecord> ParseTemporalDurationString(
3749 Isolate* isolate, DirectHandle<String> iso_string) {
3766 std::optional<ParsedISO8601Duration> parsed =
3767 TemporalParser::ParseTemporalDurationString(isolate, iso_string);
3768 if (!parsed.has_value()) {
3774 double years_mv = IfEmptyReturnZero(parsed->years);
3776 double months_mv = IfEmptyReturnZero(parsed->months);
3778 double weeks_mv = IfEmptyReturnZero(parsed->weeks);
3780 double days_mv = IfEmptyReturnZero(parsed->days);
3782 double hours_mv = IfEmptyReturnZero(parsed->whole_hours);
3803 minutes_mv = IfEmptyReturnZero(parsed->hours_fraction) * 60.0 / 1e9;
3807 minutes_mv = IfEmptyReturnZero(parsed->whole_minutes);
3827 seconds_mv = IfEmptyReturnZero(parsed->minutes_fraction) * 60.0 / 1e9;
3831 seconds_mv = parsed->whole_seconds;
3835 seconds_mv = (minutes_mv - std::floor(minutes_mv)) * 60.0;
3837 double milliseconds_mv, microseconds_mv, nanoseconds_mv;
3853 DCHECK_LE(IfEmptyReturnZero(parsed->seconds_fraction), 1e9);
3854 nanoseconds_mv = std::round(IfEmptyReturnZero(parsed->seconds_fraction));
3858 nanoseconds_mv = std::round((seconds_mv - std::floor(seconds_mv)) * 1e9);
3860 milliseconds_mv = std::floor(nanoseconds_mv / 1000000);
3862 microseconds_mv = std::floor(nanoseconds_mv / 1000) -
3863 std::floor(nanoseconds_mv / 1000000) * 1000;
3865 nanoseconds_mv -= std::floor(nanoseconds_mv / 1000) * 1000;
3871 double factor = parsed->sign;
3878 return CreateDurationRecord(
3883 {days_mv * factor, hours_mv * factor, std::floor(minutes_mv) * factor,
3884 std::floor(seconds_mv) * factor, milliseconds_mv * factor,
3885 microseconds_mv * factor, nanoseconds_mv * factor}});
3889Maybe<TimeZoneRecord> ParseTemporalTimeZoneString(
3890 Isolate* isolate, DirectHandle<String> time_zone_string) {
3895 std::optional<ParsedISO8601Result> parsed =
3896 TemporalParser::ParseTimeZoneIdentifier(isolate, time_zone_string);
3898 if (parsed.has_value()) {
3901 return Just(TimeZoneRecord(
3902 {
false, isolate->factory()->undefined_value(), time_zone_string}));
3906 DateTimeRecordWithCalendar
result;
3908 isolate,
result, ParseISODateTime(isolate, time_zone_string),
3915 if (!
result.time_zone.z && IsUndefined(*
result.time_zone.offset_string) &&
3916 IsUndefined(*
result.time_zone.name)) {
3925Maybe<int64_t> ParseTimeZoneOffsetString(Isolate* isolate,
3926 DirectHandle<String> iso_string) {
3932 std::optional<ParsedISO8601Result> parsed =
3933 TemporalParser::ParseTimeZoneNumericUTCOffset(isolate, iso_string);
3934 if (!parsed.has_value()) {
3944 if (parsed->tzuo_hour_is_undefined() || parsed->tzuo_sign_is_undefined()) {
3952 int64_t
sign = parsed->tzuo_sign;
3955 int64_t hours = parsed->tzuo_hour;
3958 parsed->tzuo_minute_is_undefined() ? 0 : parsed->tzuo_minute;
3961 parsed->tzuo_second_is_undefined() ? 0 : parsed->tzuo_second;
3964 if (!parsed->tzuo_nanosecond_is_undefined()) {
3978 return Just(
sign * (((hours * 60 + minutes) * 60 + seconds) * 1000000000 +
3982bool IsValidTimeZoneNumericUTCOffsetString(Isolate* isolate,
3983 DirectHandle<String> iso_string) {
3986 std::optional<ParsedISO8601Result> parsed =
3987 TemporalParser::ParseTimeZoneNumericUTCOffset(isolate, iso_string);
3988 return parsed.has_value();
3992MaybeDirectHandle<String> ParseTemporalCalendarString(
3993 Isolate* isolate, DirectHandle<String> iso_string) {
3997 Maybe<DateTimeRecordWithCalendar> parse_result =
3998 ParseISODateTime(isolate, iso_string);
4000 if (parse_result.IsJust()) {
4002 DirectHandle<Object>
calendar = parse_result.FromJust().calendar;
4005 return isolate->factory()->iso8601_string();
4013 DCHECK(isolate->has_exception());
4014 isolate->clear_exception();
4017 std::optional<ParsedISO8601Result> parsed =
4018 TemporalParser::ParseCalendarName(isolate, iso_string);
4020 if (!parsed.has_value()) {
4021 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidCalendar,
4030Maybe<bool> CalendarEqualsBool(Isolate* isolate, DirectHandle<JSReceiver>
one,
4031 DirectHandle<JSReceiver> two) {
4033 if (
one.is_identical_to(two)) {
4037 DirectHandle<String> calendar_one;
4041 DirectHandle<String> calendar_two;
4051MaybeDirectHandle<Oddball> CalendarEquals(Isolate* isolate,
4052 DirectHandle<JSReceiver>
one,
4053 DirectHandle<JSReceiver> two) {
4056 CalendarEqualsBool(isolate,
one, two),
4057 DirectHandle<Oddball>());
4058 return isolate->factory()->ToBoolean(
result);
4062MaybeDirectHandle<FixedArray> CalendarFields(
4063 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
4064 DirectHandle<FixedArray> field_names) {
4066 DirectHandle<Object> fields;
4070 isolate->factory()->fields_string()));
4072 DirectHandle<Object> fields_array =
4073 isolate->factory()->NewJSArrayWithElements(field_names);
4075 if (!IsUndefined(*fields)) {
4077 DirectHandle<Object>
args[] = {fields_array};
4079 isolate, fields_array,
4083 DirectHandle<Object>
args[] = {fields_array};
4085 isolate, fields_array,
4087 isolate->string_fixed_array_from_iterable(),
4089 DCHECK(IsFixedArray(*fields_array));
4093MaybeDirectHandle<JSTemporalPlainDate> CalendarDateAdd(
4094 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
4095 DirectHandle<Object>
date, DirectHandle<Object> duration) {
4097 return CalendarDateAdd(isolate,
calendar,
date, duration,
4098 isolate->factory()->undefined_value());
4101MaybeDirectHandle<JSTemporalPlainDate> CalendarDateAdd(
4102 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
4103 DirectHandle<Object>
date, DirectHandle<Object> duration,
4104 DirectHandle<Object> options) {
4105 DirectHandle<Object> date_add;
4110 isolate->factory()->dateAdd_string()));
4111 return CalendarDateAdd(isolate,
calendar,
date, duration, options, date_add);
4114MaybeDirectHandle<JSTemporalPlainDate> CalendarDateAdd(
4115 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
4116 DirectHandle<Object>
date, DirectHandle<Object> duration,
4117 DirectHandle<Object> options, DirectHandle<Object> date_add) {
4119 DCHECK(IsJSReceiver(*options) || IsUndefined(*options));
4122 DirectHandle<Object>
args[] = {
date, duration, options};
4123 DirectHandle<Object> added_date;
4125 isolate, added_date,
4128 if (!IsJSTemporalPlainDate(*added_date)) {
4135MaybeDirectHandle<JSTemporalDuration> CalendarDateUntil(
4136 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
4137 DirectHandle<Object>
one, DirectHandle<Object> two,
4138 DirectHandle<Object> options) {
4139 return CalendarDateUntil(isolate,
calendar,
one, two, options,
4140 isolate->factory()->undefined_value());
4143MaybeDirectHandle<JSTemporalDuration> CalendarDateUntil(
4144 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
4145 DirectHandle<Object>
one, DirectHandle<Object> two,
4146 DirectHandle<Object> options, DirectHandle<Object> date_until) {
4150 if (IsUndefined(*date_until)) {
4152 isolate, date_until,
4154 isolate->factory()->dateUntil_string()));
4157 DirectHandle<Object>
args[] = {
one, two, options};
4158 DirectHandle<Object> duration;
4164 if (!IsJSTemporalDuration(*duration)) {
4172MaybeDirectHandle<JSReceiver> DefaultMergeFields(
4173 Isolate* isolate, DirectHandle<JSReceiver> fields,
4174 DirectHandle<JSReceiver> additional_fields) {
4175 Factory* factory = isolate->factory();
4177 DirectHandle<JSObject> merged =
4178 isolate->factory()->NewJSObject(isolate->object_function());
4181 DirectHandle<FixedArray> original_keys;
4183 isolate, original_keys,
4188 for (
int i = 0;
i < original_keys->
length();
i++) {
4190 DirectHandle<Object> next_key(original_keys->get(
i), isolate);
4191 DCHECK(IsString(*next_key));
4192 DirectHandle<String> next_key_string =
Cast<String>(next_key);
4193 if (!(
String::Equals(isolate, factory->month_string(), next_key_string) ||
4195 next_key_string))) {
4197 DirectHandle<Object> prop_value;
4199 isolate, prop_value,
4202 if (!IsUndefined(*prop_value)) {
4212 DirectHandle<FixedArray> new_keys;
4218 bool new_keys_has_month_or_month_code =
false;
4220 for (
int i = 0;
i < new_keys->
length();
i++) {
4221 DirectHandle<Object> next_key(new_keys->get(
i), isolate);
4222 DCHECK(IsString(*next_key));
4223 DirectHandle<String> next_key_string =
Cast<String>(next_key);
4225 DirectHandle<Object> prop_value;
4227 isolate, prop_value,
4231 if (!IsUndefined(*prop_value)) {
4237 new_keys_has_month_or_month_code |=
4238 String::Equals(isolate, factory->month_string(), next_key_string) ||
4239 String::Equals(isolate, factory->monthCode_string(), next_key_string);
4242 if (!new_keys_has_month_or_month_code) {
4244 DirectHandle<Object> month;
4249 if (!IsUndefined(*month)) {
4252 factory->month_string(), month,
4257 DirectHandle<Object> month_code;
4259 isolate, month_code,
4262 if (!IsUndefined(*month_code)) {
4265 factory->monthCode_string(),
4275Maybe<int64_t> GetOffsetNanosecondsFor(Isolate* isolate,
4276 DirectHandle<JSReceiver> time_zone_obj,
4277 DirectHandle<Object> instant,
4278 const char* method_name) {
4282 DirectHandle<Object> get_offset_nanoseconds_for;
4284 isolate, get_offset_nanoseconds_for,
4286 isolate->factory()->getOffsetNanosecondsFor_string()),
4288 if (!IsCallable(*get_offset_nanoseconds_for)) {
4291 NewTypeError(MessageTemplate::kCalledNonCallable,
4292 isolate->factory()->getOffsetNanosecondsFor_string()),
4295 DirectHandle<Object> offset_nanoseconds_obj;
4298 DirectHandle<Object>
args[] = {instant};
4300 isolate, offset_nanoseconds_obj,
4306 if (!
IsNumber(*offset_nanoseconds_obj)) {
4313 if (!IsIntegralNumber(isolate, offset_nanoseconds_obj)) {
4317 double offset_nanoseconds =
4321 int64_t offset_nanoseconds_int =
static_cast<int64_t
>(offset_nanoseconds);
4323 if (std::abs(offset_nanoseconds_int) >= 86400e9) {
4328 return Just(offset_nanoseconds_int);
4332MaybeDirectHandle<Number> ToPositiveInteger(Isolate* isolate,
4333 DirectHandle<Object> argument) {
4337 DirectHandle<Number> integer;
4339 ToIntegerThrowOnInfinity(isolate, argument));
4360 Object::GetProperty(isolate,
calendar, name));
4361 if (!IsCallable(*function)) {
4363 NewTypeError(MessageTemplate::kCalledNonCallable, name));
4368 Execution::Call(isolate, function,
calendar, base::VectorOf(
args)));
4372#define CALENDAR_ABSTRACT_OPERATION_INT_ACTION(Name, name, Action) \
4373 MaybeDirectHandle<Smi> Calendar##Name(Isolate* isolate, \
4374 DirectHandle<JSReceiver> calendar, \
4375 DirectHandle<JSReceiver> date_like) { \
4378 DirectHandle<Object> result; \
4379 ASSIGN_RETURN_ON_EXCEPTION( \
4381 InvokeCalendarMethod(isolate, calendar, \
4382 isolate->factory()->name##_string(), date_like)); \
4384 if (IsUndefined(*result)) { \
4385 THROW_NEW_ERROR(isolate, NEW_TEMPORAL_INVALID_ARG_RANGE_ERROR()); \
4388 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Action(isolate, result)); \
4389 return direct_handle( \
4390 Smi::FromInt(Object::NumberValue(Cast<Number>(*result))), isolate); \
4393#define CALENDAR_ABSTRACT_OPERATION(Name, property) \
4394 MaybeDirectHandle<Object> Calendar##Name( \
4395 Isolate* isolate, DirectHandle<JSReceiver> calendar, \
4396 DirectHandle<JSReceiver> date_like) { \
4397 return InvokeCalendarMethod(isolate, calendar, \
4398 isolate->factory()->property##_string(), \
4418 isolate->factory()->monthCode_string(), date_like));
4420 if (IsUndefined(*
result)) {
4424 return Object::ToString(isolate,
result);
4427#ifdef V8_INTL_SUPPORT
4437 InvokeCalendarMethod(isolate,
calendar,
4438 isolate->factory()->eraYear_string(), date_like));
4440 if (!IsUndefined(*
result)) {
4442 ToIntegerThrowOnInfinity(isolate,
result));
4449MaybeDirectHandle<Object> CalendarEra(Isolate* isolate,
4451 DirectHandle<JSReceiver> date_like) {
4454 DirectHandle<Object>
result;
4457 InvokeCalendarMethod(isolate,
calendar, isolate->factory()->era_string(),
4460 if (!IsUndefined(*
result)) {
4462 Object::ToString(isolate,
result));
4489 return CreateTemporalCalendar(isolate, isolate->factory()->iso8601_string())
4505 if (
time_zone->length() != 3)
return false;
4508 const String::FlatContent& flat =
time_zone->GetFlatContent(no_gc);
4509 return (flat.Get(0) == u
'U' || flat.Get(0) == u
'u') &&
4510 (flat.Get(1) == u
'T' || flat.Get(1) == u
't') &&
4511 (flat.Get(2) == u
'C' || flat.Get(2) == u
'c');
4514#ifdef V8_INTL_SUPPORT
4515class CalendarMap final {
4518 icu::Locale locale(
"und");
4519 UErrorCode status = U_ZERO_ERROR;
4520 std::unique_ptr<icu::StringEnumeration> enumeration(
4521 icu::Calendar::getKeywordValuesForLocale(
"ca", locale,
false, status));
4522 calendar_ids.push_back(
"iso8601");
4523 calendar_id_indices.insert({
"iso8601", 0});
4525 for (
const char* item = enumeration->next(
nullptr, status);
4526 U_SUCCESS(status) && item !=
nullptr;
4527 item = enumeration->next(
nullptr, status)) {
4528 if (strcmp(item,
"iso8601") != 0) {
4529 const char* type = uloc_toUnicodeLocaleType(
"ca", item);
4530 calendar_ids.push_back(type);
4531 calendar_id_indices.insert({
type,
i++});
4535 bool Contains(
const std::string&
id)
const {
4536 return calendar_id_indices.
find(
id) != calendar_id_indices.end();
4539 std::string Id(int32_t index)
const {
4541 return calendar_ids[
index];
4544 int32_t Index(
const char*
id)
const {
4545 return calendar_id_indices.find(
id)->second;
4549 std::map<std::string, int32_t> calendar_id_indices;
4550 std::vector<std::string> calendar_ids;
4555bool IsBuiltinCalendar(Isolate* isolate, DirectHandle<String>
id) {
4561 return GetCalendarMap()->Contains(id->ToCString().get());
4564DirectHandle<String> CalendarIdentifier(Isolate* isolate, int32_t index) {
4565 return isolate->factory()->NewStringFromAsciiChecked(
4566 GetCalendarMap()->Id(index).c_str());
4569int32_t CalendarIndex(Isolate* isolate, DirectHandle<String>
id) {
4572 return GetCalendarMap()->Index(id->ToCString().get());
4575bool IsValidTimeZoneName(Isolate* isolate, DirectHandle<String>
time_zone) {
4579DirectHandle<String> CanonicalizeTimeZoneName(Isolate* isolate,
4585DirectHandle<String> CalendarIdentifier(Isolate* isolate, int32_t index) {
4587 return isolate->factory()->iso8601_string();
4591bool IsBuiltinCalendar(Isolate* isolate, DirectHandle<String>
id) {
4599 if (isolate->factory()->iso8601_string()->Equals(*
id))
return true;
4600 if (id->length() != 7)
return false;
4604 const String::FlatContent& flat =
id->GetFlatContent(no_gc);
4609 flat.Get(4) ==
'6' && flat.Get(5) ==
'0' && flat.Get(6) ==
'1';
4612int32_t CalendarIndex(Isolate* isolate, DirectHandle<String>
id) {
return 0; }
4615bool IsValidTimeZoneName(Isolate* isolate, DirectHandle<String>
time_zone) {
4620DirectHandle<String> CanonicalizeTimeZoneName(Isolate* isolate,
4622 return isolate->factory()->UTC_string();
4629Maybe<TimeRecord> ToTemporalTimeRecordOrPartialTime(
4630 Isolate* isolate, DirectHandle<JSReceiver> temporal_time_like,
4631 const TimeRecord& time,
bool skip_undefined,
const char* method_name) {
4635 Factory* factory = isolate->factory();
4644 std::array<std::pair<DirectHandle<String>,
int32_t*>, 6> table4 = {
4645 {{factory->hour_string(), &
result.hour},
4646 {factory->microsecond_string(), &
result.microsecond},
4647 {factory->millisecond_string(), &
result.millisecond},
4648 {factory->minute_string(), &
result.minute},
4649 {factory->nanosecond_string(), &
result.nanosecond},
4650 {factory->second_string(), &
result.second}}};
4651 for (
const auto& row : table4) {
4652 DirectHandle<Object>
value;
4660 if (!IsUndefined(*value)) {
4664 }
else if (skip_undefined) {
4668 DirectHandle<Number> value_number;
4670 ToIntegerThrowOnInfinity(isolate, value),
4688Maybe<TimeRecord> ToPartialTime(Isolate* isolate,
4689 DirectHandle<JSReceiver> temporal_time_like,
4690 const TimeRecord& time,
4691 const char* method_name) {
4692 return ToTemporalTimeRecordOrPartialTime(isolate, temporal_time_like, time,
4697Maybe<TimeRecord> ToTemporalTimeRecord(
4698 Isolate* isolate, DirectHandle<JSReceiver> temporal_time_like,
4699 const char* method_name) {
4700 return ToTemporalTimeRecordOrPartialTime(
4701 isolate, temporal_time_like,
4720Maybe<Unit> GetTemporalUnit(Isolate* isolate,
4721 DirectHandle<JSReceiver> normalized_options,
4722 const char*
key, UnitGroup unit_group,
4723 Unit default_value,
bool default_is_required,
4724 const char* method_name,
4725 Unit extra_values = Unit::kNotPresent) {
4726 std::vector<const char*> str_values;
4727 std::vector<Unit> enum_values;
4728 switch (unit_group) {
4729 case UnitGroup::kDate:
4730 if (default_value == Unit::kAuto || extra_values == Unit::kAuto) {
4731 str_values = {
"year",
"month",
"week",
"day",
"auto",
4732 "years",
"months",
"weeks",
"days"};
4733 enum_values = {Unit::kYear, Unit::kMonth, Unit::kWeek,
4734 Unit::kDay, Unit::kAuto, Unit::kYear,
4735 Unit::kMonth, Unit::kWeek, Unit::kDay};
4737 DCHECK(default_value == Unit::kNotPresent ||
4738 default_value == Unit::kYear || default_value == Unit::kMonth ||
4739 default_value == Unit::kWeek || default_value == Unit::kDay);
4740 str_values = {
"year",
"month",
"week",
"day",
4741 "years",
"months",
"weeks",
"days"};
4742 enum_values = {Unit::kYear, Unit::kMonth, Unit::kWeek, Unit::kDay,
4743 Unit::kYear, Unit::kMonth, Unit::kWeek, Unit::kDay};
4746 case UnitGroup::kTime:
4747 if (default_value == Unit::kAuto || extra_values == Unit::kAuto) {
4748 str_values = {
"hour",
"minute",
"second",
4749 "millisecond",
"microsecond",
"nanosecond",
4750 "auto",
"hours",
"minutes",
4751 "seconds",
"milliseconds",
"microseconds",
4754 Unit::kHour, Unit::kMinute, Unit::kSecond,
4755 Unit::kMillisecond, Unit::kMicrosecond, Unit::kNanosecond,
4756 Unit::kAuto, Unit::kHour, Unit::kMinute,
4757 Unit::kSecond, Unit::kMillisecond, Unit::kMicrosecond,
4759 }
else if (default_value == Unit::kDay || extra_values == Unit::kDay) {
4760 str_values = {
"hour",
"minute",
"second",
4761 "millisecond",
"microsecond",
"nanosecond",
4762 "day",
"hours",
"minutes",
4763 "seconds",
"milliseconds",
"microseconds",
4764 "nanoseconds",
"days"};
4766 Unit::kHour, Unit::kMinute, Unit::kSecond,
4767 Unit::kMillisecond, Unit::kMicrosecond, Unit::kNanosecond,
4768 Unit::kDay, Unit::kHour, Unit::kMinute,
4769 Unit::kSecond, Unit::kMillisecond, Unit::kMicrosecond,
4770 Unit::kNanosecond, Unit::kDay};
4772 DCHECK(default_value == Unit::kNotPresent ||
4773 default_value == Unit::kHour || default_value == Unit::kMinute ||
4774 default_value == Unit::kSecond ||
4775 default_value == Unit::kMillisecond ||
4776 default_value == Unit::kMicrosecond ||
4777 default_value == Unit::kNanosecond);
4778 str_values = {
"hour",
"minute",
"second",
4779 "millisecond",
"microsecond",
"nanosecond",
4780 "hours",
"minutes",
"seconds",
4781 "milliseconds",
"microseconds",
"nanoseconds"};
4783 Unit::kHour, Unit::kMinute, Unit::kSecond,
4784 Unit::kMillisecond, Unit::kMicrosecond, Unit::kNanosecond,
4785 Unit::kHour, Unit::kMinute, Unit::kSecond,
4786 Unit::kMillisecond, Unit::kMicrosecond, Unit::kNanosecond};
4789 case UnitGroup::kDateTime:
4790 if (default_value == Unit::kAuto || extra_values == Unit::kAuto) {
4791 str_values = {
"year",
"month",
"week",
4792 "day",
"hour",
"minute",
4793 "second",
"millisecond",
"microsecond",
4794 "nanosecond",
"auto",
"years",
4795 "months",
"weeks",
"days",
4796 "hours",
"minutes",
"seconds",
4797 "milliseconds",
"microseconds",
"nanoseconds"};
4799 Unit::kYear, Unit::kMonth, Unit::kWeek,
4800 Unit::kDay, Unit::kHour, Unit::kMinute,
4801 Unit::kSecond, Unit::kMillisecond, Unit::kMicrosecond,
4802 Unit::kNanosecond, Unit::kAuto, Unit::kYear,
4803 Unit::kMonth, Unit::kWeek, Unit::kDay,
4804 Unit::kHour, Unit::kMinute, Unit::kSecond,
4805 Unit::kMillisecond, Unit::kMicrosecond, Unit::kNanosecond};
4808 "year",
"month",
"week",
"day",
4809 "hour",
"minute",
"second",
"millisecond",
4810 "microsecond",
"nanosecond",
"years",
"months",
4811 "weeks",
"days",
"hours",
"minutes",
4812 "seconds",
"milliseconds",
"microseconds",
"nanoseconds"};
4814 Unit::kYear, Unit::kMonth, Unit::kWeek,
4815 Unit::kDay, Unit::kHour, Unit::kMinute,
4816 Unit::kSecond, Unit::kMillisecond, Unit::kMicrosecond,
4817 Unit::kNanosecond, Unit::kYear, Unit::kMonth,
4818 Unit::kWeek, Unit::kDay, Unit::kHour,
4819 Unit::kMinute, Unit::kSecond, Unit::kMillisecond,
4820 Unit::kMicrosecond, Unit::kNanosecond};
4826 if (default_is_required) default_value = Unit::kNotPresent;
4839 str_values, enum_values, default_value),
4844 if (default_is_required && value == Unit::kNotPresent) {
4848 MessageTemplate::kValueOutOfRange,
4849 isolate->factory()->undefined_value(),
4850 isolate->factory()->NewStringFromAsciiChecked(method_name),
4851 isolate->factory()->NewStringFromAsciiChecked(
key)),
4859MaybeDirectHandle<JSReceiver> MergeLargestUnitOption(
4860 Isolate* isolate, DirectHandle<JSReceiver> options, Unit
largest_unit) {
4863 DirectHandle<JSReceiver> merged =
4864 isolate->factory()->NewJSObjectWithNullProto();
4876 isolate, merged, isolate->factory()->largestUnit_string(),
4884MaybeDirectHandle<Number> ToIntegerThrowOnInfinity(
4885 Isolate* isolate, DirectHandle<Object> argument) {
4889 DirectHandle<Number> integer;
4901Unit LargerOfTwoTemporalUnits(Unit u1, Unit u2) {
4903 if (u1 == Unit::kYear || u2 == Unit::kYear)
return Unit::kYear;
4905 if (u1 == Unit::kMonth || u2 == Unit::kMonth)
return Unit::kMonth;
4907 if (u1 == Unit::kWeek || u2 == Unit::kWeek)
return Unit::kWeek;
4909 if (u1 == Unit::kDay || u2 == Unit::kDay)
return Unit::kDay;
4911 if (u1 == Unit::kHour || u2 == Unit::kHour)
return Unit::kHour;
4913 if (u1 == Unit::kMinute || u2 == Unit::kMinute)
return Unit::kMinute;
4915 if (u1 == Unit::kSecond || u2 == Unit::kSecond)
return Unit::kSecond;
4917 if (u1 == Unit::kMillisecond || u2 == Unit::kMillisecond)
4918 return Unit::kMillisecond;
4920 if (u1 == Unit::kMicrosecond || u2 == Unit::kMicrosecond)
4921 return Unit::kMicrosecond;
4923 return Unit::kNanosecond;
4926DirectHandle<String> UnitToString(Isolate* isolate, Unit
unit) {
4929 return isolate->factory()->year_string();
4931 return isolate->factory()->month_string();
4933 return isolate->factory()->week_string();
4935 return isolate->factory()->day_string();
4937 return isolate->factory()->hour_string();
4939 return isolate->factory()->minute_string();
4941 return isolate->factory()->second_string();
4942 case Unit::kMillisecond:
4943 return isolate->factory()->millisecond_string();
4944 case Unit::kMicrosecond:
4945 return isolate->factory()->microsecond_string();
4946 case Unit::kNanosecond:
4947 return isolate->factory()->nanosecond_string();
4948 case Unit::kNotPresent:
4955DateRecord CreateISODateRecord(Isolate* isolate,
const DateRecord&
date) {
4963DateRecord BalanceISODate(Isolate* isolate,
const DateRecord&
date) {
4968 DCHECK(std::isfinite(epoch_days));
4970 double ms =
MakeDate(epoch_days, 0);
4982 DCHECK(std::isfinite(ms));
4983 DCHECK_LT(ms,
static_cast<double>(std::numeric_limits<int64_t>::max()));
4984 DCHECK_GT(ms,
static_cast<double>(std::numeric_limits<int64_t>::min()));
4985 isolate->date_cache()->BreakDownTime(ms, &year, &month, &day, &wday, &
hour,
4988 return CreateISODateRecord(isolate, {year, month + 1, day});
4992Maybe<DateTimeRecord> AddDateTime(Isolate* isolate,
4993 const DateTimeRecord& date_time,
4995 const DurationRecord& dur,
4996 DirectHandle<Object> options) {
5001 DCHECK(ISODateTimeWithinLimits(isolate, date_time));
5005 const TimeDurationRecord& time = dur.time_duration;
5006 DateTimeRecord time_result =
5007 AddTime(isolate, date_time.time,
5008 {0, time.hours, time.minutes, time.seconds, time.milliseconds,
5009 time.microseconds, time.nanoseconds});
5012 DirectHandle<JSTemporalPlainDate> date_part;
5014 isolate, date_part, CreateTemporalDate(isolate, date_time.date,
calendar),
5018 DirectHandle<JSTemporalDuration> date_duration;
5020 isolate, date_duration,
5021 CreateTemporalDuration(
5026 {dur.time_duration.days + time_result.date.day, 0, 0, 0, 0, 0, 0}}),
5030 DirectHandle<JSTemporalPlainDate> added_date;
5032 isolate, added_date,
5033 CalendarDateAdd(isolate,
calendar, date_part, date_duration, options),
5041 time_result.date = {added_date->iso_year(), added_date->iso_month(),
5042 added_date->iso_day()};
5043 return Just(time_result);
5047Maybe<TimeDurationRecord> BalanceDuration(Isolate* isolate, Unit
largest_unit,
5048 const TimeDurationRecord& duration,
5049 const char* method_name) {
5054 isolate->factory()->undefined_value(), duration,
5058Maybe<TimeDurationRecord> BalanceDuration(Isolate* isolate, Unit
largest_unit,
5060 const char* method_name) {
5064 BalancePossiblyInfiniteDurationResult balance_result;
5066 isolate, balance_result,
5072 if (balance_result.overflow != BalanceOverflow::kNone) {
5080 return Just(balance_result.value);
5084Maybe<TimeDurationRecord> BalanceDuration(Isolate* isolate, Unit
largest_unit,
5085 const TimeDurationRecord& dur1,
5086 const TimeDurationRecord& dur2,
5087 const char* method_name) {
5090 BigInt::Add(isolate, TotalDurationNanoseconds(isolate, dur1, 0),
5091 TotalDurationNanoseconds(isolate, dur2, 0))
5097Maybe<TimeDurationRecord> BalanceDuration(Isolate* isolate, Unit
largest_unit,
5098 DirectHandle<Object> relative_to_obj,
5099 const TimeDurationRecord& value,
5100 const char* method_name) {
5104 BalancePossiblyInfiniteDurationResult balance_result;
5106 isolate, balance_result,
5107 BalancePossiblyInfiniteDuration(isolate,
largest_unit, relative_to_obj,
5108 value, method_name),
5112 if (balance_result.overflow != BalanceOverflow::kNone) {
5120 return Just(balance_result.value);
5125Maybe<BalancePossiblyInfiniteDurationResult> BalancePossiblyInfiniteDuration(
5126 Isolate* isolate, Unit
largest_unit, DirectHandle<Object> relative_to_obj,
5127 const TimeDurationRecord& value,
const char* method_name) {
5129 TimeDurationRecord duration =
value;
5134 if (IsJSTemporalZonedDateTime(*relative_to_obj)) {
5139 DirectHandle<BigInt> end_ns;
5142 AddZonedDateTime(isolate,
5146 {0, 0, 0, duration}, method_name),
5158 nanoseconds = TotalDurationNanoseconds(isolate, duration, 0);
5166 return BalancePossiblyInfiniteDuration(isolate,
largest_unit, relative_to_obj,
5174Maybe<BalancePossiblyInfiniteDurationResult> BalancePossiblyInfiniteDuration(
5175 Isolate* isolate, Unit
largest_unit, DirectHandle<Object> relative_to_obj,
5176 double days, DirectHandle<BigInt>
nanoseconds,
const char* method_name) {
5183 NanosecondsToDaysResult
result;
5186 NanosecondsToDays(isolate,
nanoseconds, relative_to_obj, method_name),
5201 DirectHandle<BigInt> hours =
zero;
5202 DirectHandle<BigInt> minutes =
zero;
5203 DirectHandle<BigInt> seconds =
zero;
5204 DirectHandle<BigInt> milliseconds =
zero;
5205 DirectHandle<BigInt> microseconds =
zero;
5230 BigInt::Divide(isolate, microseconds, thousand).ToHandleChecked();
5236 BigInt::Divide(isolate, milliseconds, thousand).ToHandleChecked();
5241 minutes =
BigInt::Divide(isolate, seconds, sixty).ToHandleChecked();
5245 hours =
BigInt::Divide(isolate, minutes, sixty).ToHandleChecked();
5259 BigInt::Divide(isolate, microseconds, thousand).ToHandleChecked();
5265 BigInt::Divide(isolate, milliseconds, thousand).ToHandleChecked();
5270 minutes =
BigInt::Divide(isolate, seconds, sixty).ToHandleChecked();
5284 BigInt::Divide(isolate, microseconds, thousand).ToHandleChecked();
5290 BigInt::Divide(isolate, milliseconds, thousand).ToHandleChecked();
5296 case Unit::kMillisecond:
5305 BigInt::Divide(isolate, microseconds, thousand).ToHandleChecked();
5311 case Unit::kMicrosecond:
5320 case Unit::kNanosecond:
5324 case Unit::kNotPresent:
5334 double minutes_value =
5336 double seconds_value =
5338 double milliseconds_value =
5340 double microseconds_value =
5342 double nanoseconds_value =
5344 if (std::isinf(
days) || std::isinf(hours_value) ||
5345 std::isinf(minutes_value) || std::isinf(seconds_value) ||
5346 std::isinf(milliseconds_value) || std::isinf(microseconds_value) ||
5347 std::isinf(nanoseconds_value)) {
5348 return Just(BalancePossiblyInfiniteDurationResult(
5349 {{0, 0, 0, 0, 0, 0, 0},
5350 sign == 1 ? BalanceOverflow::kPositive : BalanceOverflow::kNegative}));
5356 TimeDurationRecord
result;
5360 isolate,
days, hours_value *
sign, minutes_value *
sign,
5361 seconds_value *
sign, milliseconds_value *
sign,
5362 microseconds_value *
sign, nanoseconds_value *
sign),
5365 BalancePossiblyInfiniteDurationResult({
result, BalanceOverflow::kNone}));
5369MaybeDirectHandle<BigInt> AddZonedDateTime(
5370 Isolate* isolate, DirectHandle<BigInt> epoch_nanoseconds,
5372 const DurationRecord& duration,
const char* method_name) {
5377 duration, isolate->factory()->undefined_value(),
5382MaybeDirectHandle<BigInt> AddZonedDateTime(
5383 Isolate* isolate, DirectHandle<BigInt> epoch_nanoseconds,
5385 const DurationRecord& duration, DirectHandle<Object> options,
5386 const char* method_name) {
5389 TimeDurationRecord time_duration = duration.time_duration;
5391 if (duration.years == 0 && duration.months == 0 && duration.weeks == 0 &&
5392 time_duration.days == 0) {
5395 return AddInstant(isolate, epoch_nanoseconds, time_duration);
5398 DirectHandle<JSTemporalInstant> instant =
5404 DirectHandle<JSTemporalPlainDateTime> temporal_date_time;
5406 isolate, temporal_date_time,
5411 DirectHandle<JSTemporalPlainDate> date_part;
5416 {temporal_date_time->iso_year(), temporal_date_time->iso_month(),
5417 temporal_date_time->iso_day()},
5421 DirectHandle<JSTemporalDuration> date_duration;
5423 isolate, date_duration,
5424 CreateTemporalDuration(isolate,
5428 {time_duration.days, 0, 0, 0, 0, 0, 0}}));
5431 DirectHandle<JSTemporalPlainDate> added_date;
5433 isolate, added_date,
5434 CalendarDateAdd(isolate,
calendar, date_part, date_duration, options));
5441 DirectHandle<JSTemporalPlainDateTime> intermediate_date_time;
5443 isolate, intermediate_date_time,
5446 {{added_date->iso_year(), added_date->iso_month(),
5447 added_date->iso_day()},
5448 {temporal_date_time->iso_hour(), temporal_date_time->iso_minute(),
5449 temporal_date_time->iso_second(),
5450 temporal_date_time->iso_millisecond(),
5451 temporal_date_time->iso_microsecond(),
5452 temporal_date_time->iso_nanosecond()}},
5456 DirectHandle<JSTemporalInstant> intermediate_instant;
5458 isolate, intermediate_instant,
5459 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, intermediate_date_time,
5460 Disambiguation::kCompatible, method_name));
5463 time_duration.days = 0;
5464 return AddInstant(isolate,
5465 direct_handle(intermediate_instant->nanoseconds(), isolate),
5469Maybe<NanosecondsToDaysResult> NanosecondsToDays(
5470 Isolate* isolate, DirectHandle<BigInt>
nanoseconds,
5471 DirectHandle<Object> relative_to_obj,
const char* method_name) {
5474 constexpr int64_t kDayLengthNs = 86400000000000LL
U;
5483 return Just(NanosecondsToDaysResult({0, 0, kDayLengthNs}));
5497 if (!IsJSTemporalZonedDateTime(*relative_to_obj)) {
5504 DirectHandle<BigInt> days_bigint;
5506 isolate, days_bigint,
5517 return Just(NanosecondsToDaysResult(
5524 DirectHandle<BigInt> start_ns(
relative_to->nanoseconds(), isolate);
5526 DirectHandle<JSTemporalInstant> start_instant =
5536 DirectHandle<JSTemporalPlainDateTime> start_date_time;
5538 isolate, start_date_time,
5544 DirectHandle<BigInt> end_ns;
5551 if (!IsValidEpochNanoseconds(isolate, end_ns)) {
5558 DirectHandle<JSTemporalInstant> end_instant =
5563 DirectHandle<JSTemporalPlainDateTime> end_date_time;
5565 isolate, end_date_time,
5581 DurationRecord date_difference;
5583 isolate, date_difference,
5584 DifferenceISODateTime(
5586 {{start_date_time->iso_year(), start_date_time->iso_month(),
5587 start_date_time->iso_day()},
5588 {start_date_time->iso_hour(), start_date_time->iso_minute(),
5589 start_date_time->iso_second(), start_date_time->iso_millisecond(),
5590 start_date_time->iso_microsecond(),
5591 start_date_time->iso_nanosecond()}},
5592 {{end_date_time->iso_year(), end_date_time->iso_month(),
5593 end_date_time->iso_day()},
5594 {end_date_time->iso_hour(), end_date_time->iso_minute(),
5595 end_date_time->iso_second(), end_date_time->iso_millisecond(),
5596 end_date_time->iso_microsecond(), end_date_time->iso_nanosecond()}},
5597 calendar, Unit::kDay, isolate->factory()->NewJSObjectWithNullProto(),
5602 double days = date_difference.time_duration.days;
5607 DirectHandle<BigInt> intermediate_ns;
5609 isolate, intermediate_ns,
5611 {0, 0, 0, {
days, 0, 0, 0, 0, 0, 0}}, method_name),
5625 isolate, intermediate_ns,
5627 {0, 0, 0, {
days, 0, 0, 0, 0, 0, 0}}, method_name),
5645 DirectHandle<BigInt> one_day_farther_ns;
5647 isolate, one_day_farther_ns,
5649 {0, 0, 0, {
sign, 0, 0, 0, 0, 0, 0}}, method_name),
5654 isolate, day_length_ns,
5659 if (
sign * CompareResultToSign(
5669 intermediate_ns = one_day_farther_ns;
5682 NanosecondsToDaysResult
result(
5684 std::abs(day_length_ns->AsInt64())});
5689Maybe<DurationRecord> DifferenceISODateTime(Isolate* isolate,
5690 const DateTimeRecord& date_time1,
5691 const DateTimeRecord& date_time2,
5694 DirectHandle<JSReceiver> options,
5695 const char* method_name) {
5699 DCHECK(ISODateTimeWithinLimits(isolate, date_time1));
5702 DCHECK(ISODateTimeWithinLimits(isolate, date_time2));
5705 TimeDurationRecord time_difference =
5706 DifferenceTime(isolate, date_time1.time, date_time2.time).ToChecked();
5712 time_difference.days = 0;
5716 double date_sign = CompareISODate(date_time2.date, date_time1.date);
5719 DateRecord adjusted_date = date_time1.date;
5720 CHECK(IsValidISODate(isolate, adjusted_date));
5723 if (time_sign == -date_sign) {
5724 adjusted_date.day -= time_sign;
5727 adjusted_date = BalanceISODate(isolate, adjusted_date);
5733 time_difference.days = -time_sign;
5735 BalanceDuration(isolate,
largest_unit, time_difference, method_name)
5741 DirectHandle<JSTemporalPlainDate> date1 =
5742 CreateTemporalDate(isolate, adjusted_date,
calendar).ToHandleChecked();
5745 DirectHandle<JSTemporalPlainDate> date2 =
5746 CreateTemporalDate(isolate, date_time2.date,
calendar).ToHandleChecked();
5748 Unit date_largest_unit = LargerOfTwoTemporalUnits(Unit::kDay,
largest_unit);
5751 DirectHandle<JSReceiver> until_options;
5753 isolate, until_options,
5754 MergeLargestUnitOption(isolate, options, date_largest_unit),
5758 DirectHandle<JSTemporalDuration> date_difference;
5760 isolate, date_difference,
5761 CalendarDateUntil(isolate,
calendar, date1, date2, until_options),
5771 isolate, time_difference,
5772 BalanceDuration(isolate,
largest_unit, time_difference, method_name),
5781 return Just(CreateDurationRecord(
5790MaybeDirectHandle<BigInt> AddInstant(Isolate* isolate,
5791 DirectHandle<BigInt> epoch_nanoseconds,
5792 const TimeDurationRecord& addend) {
5794 Factory* factory = isolate->factory();
5803 DirectHandle<BigInt>
result =
5805 isolate, epoch_nanoseconds,
5811 DirectHandle<BigInt> temp =
5823 isolate, factory->NewNumber(addend.milliseconds))
5858 if (!IsValidEpochNanoseconds(isolate,
result)) {
5866bool IsValidEpochNanoseconds(Isolate* isolate,
5867 DirectHandle<BigInt> epoch_nanoseconds) {
5870 constexpr double kNsMinInstant = -8.64e21;
5872 constexpr double kNsMaxInstant = 8.64e21;
5878 isolate->factory()->NewNumber(kNsMinInstant)) ==
5881 isolate->factory()->NewNumber(kNsMaxInstant)) ==
5889DirectHandle<BigInt> GetEpochFromISOParts(Isolate* isolate,
5890 const DateTimeRecord& date_time) {
5895 DCHECK(IsValidISODate(isolate, date_time.date));
5898 DCHECK(IsValidTime(isolate, date_time.time));
5900 double date =
MakeDay(date_time.date.year, date_time.date.month - 1,
5901 date_time.date.day);
5903 double time =
MakeTime(date_time.time.hour, date_time.time.minute,
5904 date_time.time.second, date_time.time.millisecond);
5916 isolate->factory()->NewNumber(ms))
5942 if (dur.
years < 0)
return -1;
5943 if (dur.
years > 0)
return 1;
5944 if (dur.
months < 0)
return -1;
5945 if (dur.
months > 0)
return 1;
5946 if (dur.
weeks < 0)
return -1;
5947 if (dur.
weeks > 0)
return 1;
5949 if (time.days < 0)
return -1;
5950 if (time.days > 0)
return 1;
5951 if (time.hours < 0)
return -1;
5952 if (time.hours > 0)
return 1;
5953 if (time.minutes < 0)
return -1;
5954 if (time.minutes > 0)
return 1;
5955 if (time.seconds < 0)
return -1;
5956 if (time.seconds > 0)
return 1;
5957 if (time.milliseconds < 0)
return -1;
5958 if (time.milliseconds > 0)
return 1;
5959 if (time.microseconds < 0)
return -1;
5960 if (time.microseconds > 0)
return 1;
5961 if (time.nanoseconds < 0)
return -1;
5962 if (time.nanoseconds > 0)
return 1;
5972 int32_t
sign = DurationRecord::Sign(dur);
5980 if (!(std::isfinite(dur.
years) && std::isfinite(dur.
months) &&
5981 std::isfinite(dur.
weeks) && std::isfinite(time.days) &&
5982 std::isfinite(time.hours) && std::isfinite(time.minutes) &&
5983 std::isfinite(time.seconds) && std::isfinite(time.milliseconds) &&
5984 std::isfinite(time.microseconds) && std::isfinite(time.nanoseconds))) {
5988 time.days < 0 || time.hours < 0 || time.minutes < 0 ||
5989 time.seconds < 0 || time.milliseconds < 0 ||
5990 time.microseconds < 0 || time.nanoseconds < 0)) ||
5992 time.days > 0 || time.hours > 0 || time.minutes > 0 ||
5993 time.seconds > 0 || time.milliseconds > 0 ||
5994 time.microseconds > 0 || time.nanoseconds > 0))) {
5997 static const double kPower32Of2 =
static_cast<double>(int64_t(1) << 32);
5998 static const int64_t kPower53Of2 = int64_t(1) << 53;
6000 if (std::abs(dur.
years) >= kPower32Of2) {
6004 if (std::abs(dur.
months) >= kPower32Of2) {
6008 if (std::abs(dur.
weeks) >= kPower32Of2) {
6023 int64_t allowed = kPower53Of2;
6024 double in_seconds = std::abs(time.days * 86400.0 + time.hours * 3600.0 +
6025 time.minutes * 60.0 + time.seconds);
6027 if (in_seconds >= allowed) {
6030 allowed -= in_seconds;
6033 in_seconds = std::floor(std::abs(time.milliseconds / 1e3)) +
6034 std::floor(std::abs(time.microseconds / 1e6)) +
6035 std::floor(std::abs(time.nanoseconds / 1e9));
6036 if (in_seconds >= allowed) {
6039 allowed -= in_seconds;
6046 allowed *= 1000000000;
6047 int64_t remainders = std::abs(fmod(time.milliseconds, 1e3)) * 1000000 +
6048 std::abs(fmod(time.microseconds, 1e6)) * 1000 +
6049 std::abs(fmod(time.nanoseconds, 1e9));
6050 if (remainders >= allowed) {
6061bool IsISOLeapYear(
Isolate* isolate, int32_t year) {
6069 return isolate->date_cache()->IsLeap(year);
6073int32_t ISODaysInMonth(Isolate* isolate, int32_t year, int32_t month) {
6081 if (month % 2 == ((month < 8) ? 1 : 0))
return 31;
6083 DCHECK(month == 2 || month == 4 || month == 6 || month == 9 || month == 11);
6084 if (month != 2)
return 30;
6086 return IsISOLeapYear(isolate, year) ? 29 : 28;
6091int32_t ISODaysInYear(Isolate* isolate, int32_t year) {
6098 return IsISOLeapYear(isolate, year) ? 366 : 365;
6101bool IsValidTime(Isolate* isolate,
const TimeRecord& time) {
6106 if (time.hour < 0 || time.hour > 23)
return false;
6109 if (time.minute < 0 || time.minute > 59)
return false;
6112 if (time.second < 0 || time.second > 59)
return false;
6115 if (time.millisecond < 0 || time.millisecond > 999)
return false;
6118 if (time.microsecond < 0 || time.microsecond > 999)
return false;
6121 if (time.nanosecond < 0 || time.nanosecond > 999)
return false;
6127bool IsValidISODate(Isolate* isolate,
const DateRecord&
date) {
6146int32_t CompareISODate(
const DateRecord&
one,
const DateRecord& two) {
6151 if (
one.year > two.year)
return 1;
6153 if (
one.year < two.year)
return -1;
6155 if (
one.month > two.month)
return 1;
6157 if (
one.month < two.month)
return -1;
6159 if (
one.day > two.day)
return 1;
6161 if (
one.day < two.day)
return -1;
6166int32_t CompareTemporalTime(
const TimeRecord& time1,
const TimeRecord& time2);
6169int32_t CompareISODateTime(
const DateTimeRecord&
one,
6170 const DateTimeRecord& two) {
6172 int32_t date_result = CompareISODate(
one.date, two.date);
6174 if (date_result != 0) {
6180 return CompareTemporalTime(
one.time, two.time);
6183inline int32_t floor_divid(int32_t a, int32_t b) {
6184 return (((a) / (b)) + ((((a) < 0) && (((a) % (b)) != 0)) ? -1 : 0));
6187void BalanceISOYearMonth(Isolate* isolate, int32_t* year, int32_t* month) {
6192 *year += floor_divid((*month - 1), 12);
6194 *month =
static_cast<int32_t>(modulo(*month - 1, 12)) + 1;
6199DateTimeRecord BalanceTime(
const UnbalancedTimeRecord& input) {
6201 UnbalancedTimeRecord
time(input);
6207 time.microsecond += std::floor(time.nanosecond / 1000.0);
6209 result.nanosecond = modulo(time.nanosecond, 1000);
6211 time.millisecond += std::floor(time.microsecond / 1000.0);
6213 result.microsecond = modulo(time.microsecond, 1000);
6215 time.second += std::floor(time.millisecond / 1000.0);
6217 result.millisecond = modulo(time.millisecond, 1000);
6219 time.minute += std::floor(time.second / 60.0);
6221 result.second = modulo(time.second, 60);
6223 time.hour += std::floor(time.minute / 60.0);
6225 result.minute = modulo(time.minute, 60);
6229 result.hour = modulo(time.hour, 24);
6237Maybe<TimeDurationRecord> DifferenceTime(Isolate* isolate,
6238 const TimeRecord& time1,
6239 const TimeRecord& time2) {
6244 TimeDurationRecord dur;
6246 dur.hours = time2.hour - time1.hour;
6248 dur.minutes = time2.minute - time1.minute;
6250 dur.seconds = time2.second - time1.second;
6252 dur.milliseconds = time2.millisecond - time1.millisecond;
6254 dur.microseconds = time2.microsecond - time1.microsecond;
6256 dur.nanoseconds = time2.nanosecond - time1.nanosecond;
6263 {0, dur.hours, dur.minutes, dur.seconds, dur.milliseconds,
6264 dur.microseconds, dur.nanoseconds}});
6269 BalanceTime({dur.hours *
sign, dur.minutes *
sign, dur.seconds *
sign,
6270 dur.milliseconds *
sign, dur.microseconds *
sign,
6271 dur.nanoseconds *
sign});
6277 isolate, bt.date.day *
sign, bt.time.hour *
sign, bt.time.minute *
sign,
6278 bt.time.second *
sign, bt.time.millisecond *
sign,
6279 bt.time.microsecond *
sign, bt.time.nanosecond *
sign);
6283DateTimeRecord AddTime(Isolate* isolate,
const TimeRecord& time,
6284 const TimeDurationRecord& addend) {
6292 return BalanceTime({time.hour + addend.hours,
6294 time.minute + addend.minutes,
6296 time.second + addend.seconds,
6298 time.millisecond + addend.milliseconds,
6300 time.microsecond + addend.microseconds,
6302 time.nanosecond + addend.nanoseconds});
6308DirectHandle<BigInt> TotalDurationNanoseconds(Isolate* isolate,
6309 const TimeDurationRecord& value,
6310 double offset_shift) {
6313 TimeDurationRecord duration(value);
6317 isolate->factory()->NewNumber(value.nanoseconds))
6323 if (duration.days != 0) {
6328 isolate, isolate->factory()->NewNumber(offset_shift))
6338 DirectHandle<BigInt>
x =
6344 isolate->factory()->NewNumber(value.hours))
6352 isolate, isolate->factory()->NewNumber(value.minutes))
6359 isolate, isolate->factory()->NewNumber(value.seconds))
6366 value.milliseconds))
6373 value.microseconds))
6382Maybe<DateRecord> RegulateISODate(Isolate* isolate, ShowOverflow overflow,
6383 const DateRecord&
date);
6384Maybe<int32_t> ResolveISOMonth(Isolate* isolate,
6385 DirectHandle<JSReceiver> fields);
6388Maybe<DateRecord> ISOMonthDayFromFields(Isolate* isolate,
6389 DirectHandle<JSReceiver> fields,
6390 DirectHandle<JSReceiver> options,
6391 const char* method_name) {
6392 Factory* factory = isolate->factory();
6396 DirectHandle<FixedArray> field_names =
6397 DayMonthMonthCodeYearInFixedArray(isolate);
6400 PrepareTemporalFields(isolate, fields, field_names, RequiredFields::kDay),
6405 isolate, overflow, ToTemporalOverflow(isolate, options, method_name),
6408 DirectHandle<Object> month_obj =
6412 DirectHandle<Object> month_code_obj =
6416 DirectHandle<Object> year_obj =
6421 if (!IsUndefined(*month_obj, isolate) &&
6422 IsUndefined(*month_code_obj, isolate) &&
6423 IsUndefined(*year_obj, isolate)) {
6431 ResolveISOMonth(isolate, fields),
6435 DirectHandle<Object> day_obj =
6445 int32_t reference_iso_year = 1972;
6447 if (IsUndefined(*month_code_obj, isolate)) {
6454 result.year = reference_iso_year;
6457 isolate,
result, RegulateISODate(isolate, overflow,
result),
6461 result.year = reference_iso_year;
6476 const char* method_name =
"Temporal.Duration";
6481 NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
6482 isolate->factory()->NewStringFromAsciiChecked(
6488 isolate,
y, ToIntegerWithoutRounding(isolate,
years),
6494 isolate, mo, ToIntegerWithoutRounding(isolate,
months),
6500 isolate, w, ToIntegerWithoutRounding(isolate,
weeks),
6506 isolate, d, ToIntegerWithoutRounding(isolate,
days),
6512 isolate, h, ToIntegerWithoutRounding(isolate, hours),
6518 isolate,
m, ToIntegerWithoutRounding(isolate, minutes),
6524 isolate, s, ToIntegerWithoutRounding(isolate, seconds),
6530 isolate, ms, ToIntegerWithoutRounding(isolate, milliseconds),
6536 isolate, mis, ToIntegerWithoutRounding(isolate, microseconds),
6542 isolate, ns, ToIntegerWithoutRounding(isolate,
nanoseconds),
6547 return CreateTemporalDuration(isolate, target,
new_target,
6548 {
y, mo, w, {d, h,
m,
s, ms, mis, ns}});
6556 const char* method_name);
6573 const char* method_name);
6580 const char* method_name);
6586 const char* method_name);
6592 const char* method_name) {
6597 if (!IsJSTemporalZonedDateTime(*relative_to_obj) ||
6598 (
unit == Unit::kYear ||
unit == Unit::kMonth ||
unit == Unit::kWeek ||
6599 unit == Unit::kDay) ||
6603 return Just(CreateDurationRecord(isolate, duration).ToChecked());
6605 DirectHandle<JSTemporalZonedDateTime>
relative_to =
6609 DirectHandle<BigInt> time_remainder_ns = TotalDurationNanoseconds(
6633 DirectHandle<BigInt> day_start;
6636 AddZonedDateTime(isolate,
6643 {duration.time_duration.days, 0, 0, 0, 0, 0, 0}},
6648 DirectHandle<BigInt> day_end;
6651 AddZonedDateTime(isolate, day_start,
6654 {0, 0, 0, {direction, 0, 0, 0, 0, 0, 0}}, method_name),
6657 DirectHandle<BigInt> day_length_ns =
6660 DirectHandle<BigInt> time_remainder_ns_minus_day_length_ns =
6664 if (time_remainder_ns_minus_day_length_ns->AsInt64() *
direction < 0) {
6667 return Just(CreateDurationRecord(isolate, duration).ToChecked());
6672 RoundTemporalInstant(isolate, time_remainder_ns_minus_day_length_ns,
6676 DurationRecord adjusted_date_duration;
6678 isolate, adjusted_date_duration,
6679 AddDuration(isolate,
6684 {0, 0, 0, {
direction, 0, 0, 0, 0, 0, 0}},
relative_to,
6689 TimeDurationRecord adjusted_time_duration;
6691 isolate, adjusted_time_duration,
6692 BalanceDuration(isolate, Unit::kHour, time_remainder_ns, method_name),
6701 adjusted_time_duration.days = adjusted_date_duration.time_duration.days;
6703 CreateDurationRecord(
6704 isolate, {adjusted_date_duration.years, adjusted_date_duration.months,
6705 adjusted_date_duration.weeks, adjusted_time_duration})
6710Maybe<int64_t> CalculateOffsetShift(Isolate* isolate,
6711 DirectHandle<Object> relative_to_obj,
6712 const DateDurationRecord& dur,
6713 const char* method_name) {
6718 if (!IsJSTemporalZonedDateTime(*relative_to_obj)) {
6719 return Just(
static_cast<int64_t
>(0));
6723 DirectHandle<JSTemporalInstant> instant =
6729 int64_t offset_before;
6731 isolate, offset_before,
6732 GetOffsetNanosecondsFor(isolate,
6734 instant, method_name),
6739 DirectHandle<BigInt> after;
6746 {dur.years, dur.months, dur.weeks, {dur.days, 0, 0, 0, 0, 0, 0}},
6750 DirectHandle<JSTemporalInstant> instant_after =
6754 int64_t offset_after;
6756 isolate, offset_after,
6757 GetOffsetNanosecondsFor(isolate,
6759 instant_after, method_name),
6762 return Just(offset_after - offset_before);
6766struct MoveRelativeDateResult {
6770Maybe<MoveRelativeDateResult> MoveRelativeDate(
6771 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
6773 DirectHandle<JSTemporalDuration> duration,
const char* method_name);
6776Maybe<DateDurationRecord> UnbalanceDurationRelative(
6777 Isolate* isolate,
const DateDurationRecord& dur, Unit
largest_unit,
6778 DirectHandle<Object> relative_to_obj,
const char* method_name) {
6781 Factory* factory = isolate->factory();
6785 (dur.years == 0 && dur.months == 0 && dur.weeks == 0 && dur.days == 0)) {
6787 return Just(DateDurationRecord::Create(isolate, dur.years, dur.months,
6788 dur.weeks, dur.days)
6794 {dur.years, dur.months, dur.weeks, {dur.days, 0, 0, 0, 0, 0, 0}});
6799 DirectHandle<JSTemporalDuration> one_year =
6800 CreateTemporalDuration(isolate, {
sign, 0, 0, {0, 0, 0, 0, 0, 0, 0}})
6804 DirectHandle<JSTemporalDuration> one_month =
6805 CreateTemporalDuration(isolate, {0,
sign, 0, {0, 0, 0, 0, 0, 0, 0}})
6809 DirectHandle<JSTemporalDuration> one_week =
6810 CreateTemporalDuration(isolate, {0, 0,
sign, {0, 0, 0, 0, 0, 0, 0}})
6815 if (!IsUndefined(*relative_to_obj)) {
6819 ToTemporalDate(isolate, relative_to_obj, method_name),
6827 DateDurationRecord
result = dur;
6838 DirectHandle<Object> date_add;
6844 DirectHandle<Object> date_until;
6846 isolate, date_until,
6850 while (
result.years != 0) {
6853 DirectHandle<JSTemporalPlainDate> new_relative_to;
6855 isolate, new_relative_to,
6857 factory->undefined_value(), date_add),
6860 DirectHandle<JSObject> until_options =
6861 factory->NewJSObjectWithNullProto();
6865 isolate, until_options, factory->largestUnit_string(),
6870 DirectHandle<JSTemporalDuration> until_result;
6872 isolate, until_result,
6874 until_options, date_until),
6883 result.months += one_year_months;
6895 while (
result.years != 0) {
6897 MoveRelativeDateResult move_result;
6899 isolate, move_result,
6906 result.days += move_result.days;
6911 while (
result.months != 0) {
6914 MoveRelativeDateResult move_result;
6916 isolate, move_result,
6923 result.days += move_result.days;
6939 while (
result.years != 0) {
6942 MoveRelativeDateResult move_result;
6944 isolate, move_result,
6951 result.days += move_result.days;
6956 while (
result.months != 0) {
6959 MoveRelativeDateResult move_result;
6961 isolate, move_result,
6968 result.days += move_result.days;
6973 while (
result.weeks != 0) {
6976 MoveRelativeDateResult move_result;
6978 isolate, move_result,
6985 result.days += move_result.days;
6992 return DateDurationRecord::Create(isolate,
result.years,
result.months,
6997Maybe<DateDurationRecord> BalanceDurationRelative(
6998 Isolate* isolate,
const DateDurationRecord& dur, Unit
largest_unit,
6999 DirectHandle<Object> relative_to_obj,
const char* method_name) {
7002 Factory* factory = isolate->factory();
7008 (dur.years == 0 && dur.months == 0 && dur.weeks == 0 && dur.days == 0)) {
7010 return Just(DateDurationRecord::Create(isolate, dur.years, dur.months,
7011 dur.weeks, dur.days)
7015 if (IsUndefined(*relative_to_obj)) {
7025 {dur.years, dur.months, dur.weeks, {dur.days, 0, 0, 0, 0, 0, 0}});
7030 DirectHandle<JSTemporalDuration> one_year =
7031 CreateTemporalDuration(isolate, {
sign, 0, 0, {0, 0, 0, 0, 0, 0, 0}})
7035 DirectHandle<JSTemporalDuration> one_month =
7036 CreateTemporalDuration(isolate, {0,
sign, 0, {0, 0, 0, 0, 0, 0, 0}})
7040 DirectHandle<JSTemporalDuration> one_week =
7041 CreateTemporalDuration(isolate, {0, 0,
sign, {0, 0, 0, 0, 0, 0, 0}})
7047 ToTemporalDate(isolate, relative_to_obj, method_name),
7052 DateDurationRecord
result = dur;
7056 MoveRelativeDateResult move_result;
7058 isolate, move_result,
7062 DirectHandle<JSTemporalPlainDate> new_relative_to = move_result.relative_to;
7064 double one_year_days = move_result.days;
7066 while (std::abs(
result.days) >= std::abs(one_year_days)) {
7068 result.days -= one_year_days;
7076 isolate, move_result,
7082 new_relative_to = move_result.relative_to;
7084 one_year_days = move_result.days;
7088 isolate, move_result,
7093 new_relative_to = move_result.relative_to;
7095 double one_month_days = move_result.days;
7097 while (std::abs(
result.days) >= std::abs(one_month_days)) {
7099 result.days -= one_month_days;
7107 isolate, move_result,
7112 new_relative_to = move_result.relative_to;
7114 one_month_days = move_result.days;
7117 DirectHandle<Object> date_add;
7125 isolate, new_relative_to,
7127 factory->undefined_value(), date_add),
7130 DirectHandle<Object> date_until;
7132 isolate, date_until,
7136 DirectHandle<JSObject> until_options = factory->NewJSObjectWithNullProto();
7140 isolate, until_options, factory->largestUnit_string(),
7145 DirectHandle<JSTemporalDuration> until_result;
7147 isolate, until_result,
7149 until_options, date_until),
7154 while (std::abs(
result.months) >= std::abs(one_year_months)) {
7156 result.months -= one_year_months;
7164 isolate, new_relative_to,
7166 factory->undefined_value(), date_add),
7169 until_options = factory->NewJSObjectWithNullProto();
7173 isolate, until_options, factory->largestUnit_string(),
7179 isolate, until_result,
7181 until_options, date_until),
7189 MoveRelativeDateResult move_result;
7191 isolate, move_result,
7196 DirectHandle<JSTemporalPlainDate> new_relative_to = move_result.relative_to;
7198 double one_month_days = move_result.days;
7200 while (std::abs(
result.days) >= std::abs(one_month_days)) {
7202 result.days -= one_month_days;
7210 isolate, move_result,
7215 new_relative_to = move_result.relative_to;
7217 one_month_days = move_result.days;
7224 MoveRelativeDateResult move_result;
7226 isolate, move_result,
7230 DirectHandle<JSTemporalPlainDate> new_relative_to = move_result.relative_to;
7232 double one_week_days = move_result.days;
7234 while (std::abs(
result.days) >= std::abs(one_week_days)) {
7236 result.days -= one_week_days;
7244 isolate, move_result,
7249 new_relative_to = move_result.relative_to;
7251 one_week_days = move_result.days;
7255 return DateDurationRecord::Create(isolate,
result.years,
result.months,
7265 const char* method_name =
"Temporal.Duration.compare";
7284 ToRelativeTemporalObject(isolate, options, method_name));
7290 CalculateOffsetShift(
7302 CalculateOffsetShift(
7311 double days1, days2;
7320 DateDurationRecord unbalance_result1;
7322 isolate, unbalance_result1,
7323 UnbalanceDurationRelative(isolate,
7332 DateDurationRecord unbalance_result2;
7334 isolate, unbalance_result2,
7335 UnbalanceDurationRelative(isolate,
7343 days1 = unbalance_result1.days;
7345 days2 = unbalance_result2.days;
7393 if (IsJSTemporalDuration(*item)) {
7399 return CreateTemporalDuration(
7421Maximum MaximumTemporalDurationRoundingIncrement(Unit
unit);
7423Maybe<double> ToTemporalRoundingIncrement(
7424 Isolate* isolate, DirectHandle<JSReceiver> normalized_options,
7425 double dividend,
bool dividend_is_defined,
bool inclusive);
7428MaybeDirectHandle<JSTemporalZonedDateTime> MoveRelativeZonedDateTime(
7429 Isolate* isolate, DirectHandle<JSTemporalZonedDateTime> zoned_date_time,
7430 const DateDurationRecord& duration,
const char* method_name);
7433Maybe<DurationRecordWithRemainder> RoundDuration(
7434 Isolate* isolate,
const DurationRecord& duration,
double increment,
7436 const char* method_name);
7443 const char* method_name =
"Temporal.Duration.prototype.round";
7444 Factory* factory = isolate->factory();
7449 if (IsUndefined(*round_to_obj)) {
7455 if (IsString(*round_to_obj)) {
7463 factory->smallestUnit_string(),
7473 bool smallest_unit_present =
true;
7475 bool largest_unit_present =
true;
7481 GetTemporalUnit(isolate, round_to,
"smallestUnit", UnitGroup::kDateTime,
7482 Unit::kNotPresent,
false, method_name),
7487 smallest_unit_present =
false;
7496 Unit default_largest_unit = DefaultTemporalLargestUnit(
7510 default_largest_unit =
7511 LargerOfTwoTemporalUnits(default_largest_unit,
smallest_unit);
7517 GetTemporalUnit(isolate, round_to,
"largestUnit", UnitGroup::kDateTime,
7518 Unit::kNotPresent,
false, method_name, Unit::kAuto),
7523 largest_unit_present =
false;
7532 if (!smallest_unit_present && !largest_unit_present) {
7545 ToTemporalRoundingMode(isolate, round_to, RoundingMode::kHalfExpand,
7550 Maximum maximum = MaximumTemporalDurationRoundingIncrement(
smallest_unit);
7557 ToTemporalRoundingIncrement(isolate, round_to, maximum.value,
7558 maximum.defined,
false),
7564 ToRelativeTemporalObject(isolate, round_to, method_name));
7568 DateDurationRecord unbalance_result;
7570 isolate, unbalance_result,
7571 UnbalanceDurationRelative(isolate,
7584 DurationRecordWithRemainder round_result;
7586 isolate, round_result,
7589 {unbalance_result.years,
7590 unbalance_result.months,
7591 unbalance_result.weeks,
7610 isolate, adjust_result,
7611 AdjustRoundedDurationDays(isolate, round_result.record,
7618 DateDurationRecord balance_result;
7620 isolate, balance_result,
7621 BalanceDurationRelative(
7623 {adjust_result.years, adjust_result.months, adjust_result.weeks,
7624 adjust_result.time_duration.days},
7635 MoveRelativeZonedDateTime(isolate,
7637 {balance_result.years, balance_result.months,
7638 balance_result.weeks, 0},
7645 TimeDurationRecord
result;
7649 {balance_result.days, adjust_result.time_duration.hours,
7650 adjust_result.time_duration.minutes,
7651 adjust_result.time_duration.seconds,
7652 adjust_result.time_duration.milliseconds,
7653 adjust_result.time_duration.microseconds,
7654 adjust_result.time_duration.nanoseconds},
7661 return CreateTemporalDuration(isolate,
7662 {balance_result.years, balance_result.months,
7663 balance_result.weeks,
result})
7671 const char* method_name =
"Temporal.Duration.prototype.total";
7672 Factory* factory = isolate->factory();
7677 if (IsUndefined(*total_of_obj, isolate)) {
7683 if (IsString(*total_of_obj)) {
7690 factory->unit_string(), param_string,
7704 ToRelativeTemporalObject(isolate, total_of, method_name));
7709 GetTemporalUnit(isolate, total_of,
"unit", UnitGroup::kDateTime,
7710 Unit::kNotPresent,
true, method_name),
7715 DateDurationRecord unbalance_result;
7717 isolate, unbalance_result,
7718 UnbalanceDurationRelative(isolate,
7736 isolate, intermediate,
7737 MoveRelativeZonedDateTime(
7739 {unbalance_result.years, unbalance_result.months,
7740 unbalance_result.weeks, 0},
7749 BalancePossiblyInfiniteDurationResult balance_result;
7751 isolate, balance_result,
7752 BalancePossiblyInfiniteDuration(
7753 isolate,
unit, intermediate,
7763 if (balance_result.overflow == BalanceOverflow::kPositive) {
7764 return factory->infinity_value();
7767 if (balance_result.overflow == BalanceOverflow::kNegative) {
7768 return factory->minus_infinity_value();
7771 DCHECK_EQ(balance_result.overflow, BalanceOverflow::kNone);
7778 DurationRecordWithRemainder round_record;
7780 isolate, round_record,
7781 RoundDuration(isolate,
7782 {unbalance_result.years, unbalance_result.months,
7783 unbalance_result.weeks, balance_result.value},
7794 whole = round_result.years;
7799 whole = round_result.months;
7804 whole = round_result.weeks;
7809 whole = round_result.time_duration.days;
7814 whole = round_result.time_duration.hours;
7819 whole = round_result.time_duration.minutes;
7824 whole = round_result.time_duration.seconds;
7827 case Unit::kMillisecond:
7829 whole = round_result.time_duration.milliseconds;
7832 case Unit::kMicrosecond:
7834 whole = round_result.time_duration.microseconds;
7837 case Unit::kNanosecond:
7839 whole = round_result.time_duration.nanoseconds;
7845 return factory->
NewNumber(whole + round_record.remainder);
7854 if (!IsJSReceiver(*temporal_duration_like_obj)) {
7875 isolate, temporal_duration_like,
7878 bool not_undefined =
false;
7887 if (!IsUndefined(*val)) {
7889 not_undefined =
true;
7894 isolate, *field, ToIntegerWithoutRounding(isolate, val),
7897 return Just(not_undefined);
7922 isolate, temporal_duration_like,
7937 return CreateTemporalDuration(isolate, partial);
7987 return isolate->factory()->ToBoolean(
sign == 0);
7995 return CreateDurationRecord(
8008MaybeDirectHandle<JSTemporalDuration> CreateNegatedTemporalDuration(
8009 Isolate* isolate, DirectHandle<JSTemporalDuration> duration) {
8018 return CreateTemporalDuration(
8042 return CreateNegatedTemporalDuration(isolate, duration).
ToHandleChecked();
8056 return CreateTemporalDuration(
8073 Isolate* isolate,
const DateTimeRecord& data,
8074 OffsetBehaviour offset_behaviour, int64_t offset_nanoseconds,
8076 Offset offset_option, MatchBehaviour match_behaviour,
8077 const char* method_name);
8083 const char* method_name);
8088 const char* method_name) {
8091 Factory* factory = isolate->factory();
8099 if (IsUndefined(*value_obj)) {
8104 OffsetBehaviour offset_behaviour = OffsetBehaviour::kOption;
8107 MatchBehaviour match_behaviour = MatchBehaviour::kMatchExactly;
8109 DirectHandle<Object> time_zone_obj = factory->undefined_value();
8110 DirectHandle<Object> offset_string_obj;
8111 temporal::DateTimeRecord
result;
8114 if (IsJSReceiver(*value_obj)) {
8118 if (IsJSTemporalPlainDate(*value) || IsJSTemporalZonedDateTime(*value)) {
8123 if (IsJSTemporalPlainDateTime(*value)) {
8128 return CreateTemporalDate(
8130 {date_time_value->iso_year(), date_time_value->iso_month(),
8131 date_time_value->iso_day()},
8137 GetTemporalCalendarWithISODefault(isolate, value, method_name));
8141 DirectHandle<FixedArray> field_names = All10UnitsInFixedArray(isolate);
8143 CalendarFields(isolate,
calendar, field_names));
8145 DirectHandle<JSReceiver> fields;
8148 PrepareTemporalFields(isolate, value, field_names,
8149 RequiredFields::kNone));
8155 isolate, date_options, factory->overflow_string(),
8162 InterpretTemporalDateTimeFields(isolate,
calendar, fields, date_options,
8164 DirectHandle<Object>());
8167 isolate, offset_string_obj,
8171 isolate, time_zone_obj,
8174 if (!IsUndefined(*time_zone_obj)) {
8184 if (IsUndefined(*offset_string_obj)) {
8186 offset_behaviour = OffsetBehaviour::kWall;
8191 DirectHandle<String>
string;
8194 DateTimeRecordWithCalendar parsed_result;
8197 isolate, parsed_result, ParseTemporalRelativeToString(isolate,
string),
8198 DirectHandle<Object>());
8199 result = {parsed_result.date, parsed_result.time};
8204 ToTemporalCalendarWithISODefault(isolate, parsed_result.calendar,
8208 offset_string_obj = parsed_result.time_zone.offset_string;
8211 DirectHandle<Object> time_zone_name_obj = parsed_result.time_zone.name;
8214 if (IsUndefined(*time_zone_name_obj)) {
8216 time_zone_obj = factory->undefined_value();
8221 DCHECK(IsString(*time_zone_name_obj));
8222 DirectHandle<String> time_zone_name =
Cast<String>(time_zone_name_obj);
8223 std::optional<ParsedISO8601Result> parsed =
8224 TemporalParser::ParseTimeZoneNumericUTCOffset(isolate,
8226 if (!parsed.has_value()) {
8229 if (!IsValidTimeZoneName(isolate, time_zone_name)) {
8232 DirectHandle<Object>());
8235 time_zone_name = CanonicalizeTimeZoneName(isolate, time_zone_name);
8238 DirectHandle<JSTemporalTimeZone>
time_zone =
8244 if (parsed_result.time_zone.z) {
8246 offset_behaviour = OffsetBehaviour::kExact;
8248 }
else if (IsUndefined(*offset_string_obj)) {
8250 offset_behaviour = OffsetBehaviour::kWall;
8253 match_behaviour = MatchBehaviour::kMatchMinutes;
8257 if (IsUndefined(*time_zone_obj)) {
8262 DCHECK(IsJSReceiver(*time_zone_obj));
8265 int64_t offset_ns = 0;
8266 if (offset_behaviour == OffsetBehaviour::kOption) {
8273 isolate, offset_ns, ParseTimeZoneOffsetString(isolate,
offset_string),
8274 DirectHandle<Object>());
8285 DirectHandle<BigInt> epoch_nanoseconds;
8287 isolate, epoch_nanoseconds,
8288 InterpretISODateTimeOffset(isolate,
result, offset_behaviour, offset_ns,
8290 Offset::kReject, match_behaviour,
8295 return CreateTemporalZonedDateTime(isolate, epoch_nanoseconds,
time_zone,
8300Unit DefaultTemporalLargestUnit(
const DurationRecord& dur) {
8302 if (dur.years != 0)
return Unit::kYear;
8304 if (dur.months != 0)
return Unit::kMonth;
8306 if (dur.weeks != 0)
return Unit::kWeek;
8308 if (dur.time_duration.days != 0)
return Unit::kDay;
8310 if (dur.time_duration.hours != 0)
return Unit::kHour;
8312 if (dur.time_duration.minutes != 0)
return Unit::kMinute;
8314 if (dur.time_duration.seconds != 0)
return Unit::kSecond;
8316 if (dur.time_duration.milliseconds != 0)
return Unit::kMillisecond;
8318 if (dur.time_duration.microseconds != 0)
return Unit::kMicrosecond;
8320 return Unit::kNanosecond;
8324Maybe<DurationRecord> DifferenceZonedDateTime(
8325 Isolate* isolate, DirectHandle<BigInt> ns1, DirectHandle<BigInt> ns2,
8328 const char* method_name) {
8334 return Just(CreateDurationRecord(isolate, {0, 0, 0, {0, 0, 0, 0, 0, 0, 0}})
8338 DirectHandle<JSTemporalInstant> start_instant =
8343 DirectHandle<JSTemporalPlainDateTime> start_date_time;
8345 isolate, start_date_time,
8350 DirectHandle<JSTemporalInstant> end_instant =
8355 DirectHandle<JSTemporalPlainDateTime> end_date_time;
8357 isolate, end_date_time,
8371 DurationRecord date_difference;
8373 isolate, date_difference,
8374 DifferenceISODateTime(
8376 {{start_date_time->iso_year(), start_date_time->iso_month(),
8377 start_date_time->iso_day()},
8378 {start_date_time->iso_hour(), start_date_time->iso_minute(),
8379 start_date_time->iso_second(), start_date_time->iso_millisecond(),
8380 start_date_time->iso_microsecond(),
8381 start_date_time->iso_nanosecond()}},
8382 {{end_date_time->iso_year(), end_date_time->iso_month(),
8383 end_date_time->iso_day()},
8384 {end_date_time->iso_hour(), end_date_time->iso_minute(),
8385 end_date_time->iso_second(), end_date_time->iso_millisecond(),
8386 end_date_time->iso_microsecond(), end_date_time->iso_nanosecond()}},
8393 DirectHandle<BigInt> intermediate_ns;
8395 isolate, intermediate_ns,
8397 {date_difference.years,
8398 date_difference.months,
8399 date_difference.weeks,
8400 {0, 0, 0, 0, 0, 0, 0}},
8404 DirectHandle<BigInt> time_remainder_ns =
8409 DirectHandle<JSTemporalZonedDateTime> intermediate =
8414 NanosecondsToDaysResult
result;
8417 NanosecondsToDays(isolate, time_remainder_ns, intermediate, method_name),
8422 TimeDurationRecord time_difference =
8423 BalanceDuration(isolate, Unit::kHour,
8424 {0, 0, 0, 0, 0, 0,
result.nanoseconds}, method_name)
8432 time_difference.days =
result.days;
8433 return Just(CreateDurationRecord(
8434 isolate, {date_difference.years, date_difference.months,
8435 date_difference.weeks, time_difference})
8439Maybe<DurationRecord> AddDuration(Isolate* isolate,
const DurationRecord& dur1,
8440 const DurationRecord& dur2,
8441 DirectHandle<Object> relative_to_obj,
8442 const char* method_name) {
8445 Factory* factory = isolate->factory();
8449 Unit largest_unit1 = DefaultTemporalLargestUnit(dur1);
8452 Unit largest_unit2 = DefaultTemporalLargestUnit(dur2);
8455 Unit
largest_unit = LargerOfTwoTemporalUnits(largest_unit1, largest_unit2);
8458 if (IsUndefined(*relative_to_obj)) {
8472 isolate,
result.time_duration,
8473 BalanceDuration(isolate,
largest_unit, dur1.time_duration,
8474 dur2.time_duration, method_name),
8481 return Just(CreateDurationRecord(isolate, {0, 0, 0,
result.time_duration})
8484 }
else if (IsJSTemporalPlainDate(*relative_to_obj)) {
8491 DirectHandle<JSTemporalDuration> date_duration1;
8493 isolate, date_duration1,
8494 CreateTemporalDuration(isolate,
8498 {dur1.time_duration.days, 0, 0, 0, 0, 0, 0}}),
8502 DirectHandle<JSTemporalDuration> date_duration2;
8504 isolate, date_duration2,
8505 CreateTemporalDuration(isolate,
8509 {dur2.time_duration.days, 0, 0, 0, 0, 0, 0}}),
8512 DirectHandle<Object> date_add;
8519 DirectHandle<JSTemporalPlainDate> intermediate;
8521 isolate, intermediate,
8523 factory->undefined_value(), date_add),
8527 DirectHandle<JSTemporalPlainDate>
end;
8530 CalendarDateAdd(isolate,
calendar, intermediate, date_duration2,
8531 factory->undefined_value(), date_add),
8534 Unit date_largest_unit = LargerOfTwoTemporalUnits(Unit::kDay,
largest_unit);
8536 DirectHandle<JSObject> difference_options =
8537 factory->NewJSObjectWithNullProto();
8541 isolate, difference_options, factory->largestUnit_string(),
8547 DirectHandle<JSTemporalDuration> date_difference;
8549 isolate, date_difference,
8551 difference_options),
8557 TimeDurationRecord time_dur1 = dur1.time_duration;
8559 TimeDurationRecord time_dur2 = dur2.time_duration;
8562 isolate,
result.time_duration,
8563 BalanceDuration(isolate,
largest_unit, time_dur1, time_dur2,
8571 return Just(CreateDurationRecord(
8580 DCHECK(IsJSTemporalZonedDateTime(*relative_to_obj));
8588 DirectHandle<BigInt> intermediate_ns;
8590 isolate, intermediate_ns,
8591 AddZonedDateTime(isolate,
8597 DirectHandle<BigInt> end_ns;
8608 result.time_duration = DifferenceInstant(
8610 Unit::kNanosecond,
largest_unit, RoundingMode::kHalfExpand,
8615 result.time_duration.days = 0;
8616 return Just(CreateDurationRecord(isolate, {0, 0, 0,
result.time_duration})
8621 return DifferenceZonedDateTime(
8627MaybeDirectHandle<JSTemporalDuration>
8628AddDurationToOrSubtractDurationFromDuration(
8629 Isolate* isolate, Arithmetic operation,
8630 DirectHandle<JSTemporalDuration> duration, DirectHandle<Object> other_obj,
8631 DirectHandle<Object> options_obj,
const char* method_name) {
8633 double sign = operation == Arithmetic::kSubtract ? -1.0 : 1.0;
8636 DurationRecord other;
8640 DirectHandle<JSTemporalDuration>());
8643 DirectHandle<JSReceiver>
options;
8651 ToRelativeTemporalObject(isolate, options, method_name));
8676 {
sign * other.years,
8677 sign * other.months,
8679 {
sign * other.time_duration.days,
sign * other.time_duration.hours,
8680 sign * other.time_duration.minutes,
8681 sign * other.time_duration.seconds,
8682 sign * other.time_duration.milliseconds,
8683 sign * other.time_duration.microseconds,
8684 sign * other.time_duration.nanoseconds}},
8686 DirectHandle<JSTemporalDuration>());
8692 return CreateTemporalDuration(isolate,
result).ToHandleChecked();
8701 return AddDurationToOrSubtractDurationFromDuration(
8702 isolate, Arithmetic::kAdd, duration, other, options,
8703 "Temporal.Duration.prototype.add");
8710 return AddDurationToOrSubtractDurationFromDuration(
8711 isolate, Arithmetic::kSubtract, duration, other, options,
8712 "Temporal.Duration.prototype.subtract");
8736 return TemporalDurationToString(isolate, dur, Precision::kAuto);
8763 return TemporalDurationToString(isolate, dur, Precision::kAuto);
8770 const DateDurationRecord& duration,
const char* method_name) {
8776 isolate, intermediate_ns,
8777 AddZonedDateTime(isolate,
8784 {duration.days, 0, 0, 0, 0, 0, 0}},
8788 return CreateTemporalZonedDateTime(
8789 isolate, intermediate_ns,
8796double DaysUntil(Isolate* isolate, DirectHandle<JSTemporalPlainDate> earlier,
8797 DirectHandle<JSTemporalPlainDate> later,
8798 const char* method_name) {
8801 double epoch_days1 =
MakeDay(earlier->iso_year(), earlier->iso_month() - 1,
8802 earlier->iso_day());
8806 double epoch_days2 =
8807 MakeDay(later->iso_year(), later->iso_month() - 1, later->iso_day());
8810 return epoch_days2 - epoch_days1;
8814Maybe<MoveRelativeDateResult> MoveRelativeDate(
8815 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
8817 DirectHandle<JSTemporalDuration> duration,
const char* method_name) {
8819 DirectHandle<JSTemporalPlainDate> new_date;
8827 return Just(MoveRelativeDateResult({new_date,
days}));
8831Maybe<DurationRecordWithRemainder> RoundDuration(
8832 Isolate* isolate,
const DurationRecord& duration,
double increment,
8834 const char* method_name) {
8841 Factory* factory = isolate->factory();
8842 DurationRecordWithRemainder
result;
8843 result.record = duration;
8845 if ((
unit == Unit::kYear ||
unit == Unit::kMonth ||
unit == Unit::kWeek) &&
8854 DirectHandle<Object> zoned_relative_to =
8855 isolate->factory()->undefined_value();
8866 DirectHandle<JSTemporalPlainDate>
date;
8878 calendar = DirectHandle<JSReceiver>(
8884 double fractional_seconds = 0;
8886 if (
unit == Unit::kYear ||
unit == Unit::kMonth ||
unit == Unit::kWeek ||
8887 unit == Unit::kDay) {
8890 TimeDurationRecord time_duration = duration.time_duration;
8891 time_duration.days = 0;
8893 TotalDurationNanoseconds(isolate, time_duration, 0);
8896 DirectHandle<Object> intermediate = isolate->factory()->undefined_value();
8899 if (!IsUndefined(*zoned_relative_to)) {
8900 DCHECK(IsJSTemporalZonedDateTime(*zoned_relative_to));
8904 isolate, intermediate,
8905 MoveRelativeZonedDateTime(
8907 {duration.years, duration.months, duration.weeks,
8908 duration.time_duration.days},
8914 NanosecondsToDaysResult to_days_result;
8916 isolate, to_days_result,
8917 NanosecondsToDays(isolate,
nanoseconds, intermediate, method_name),
8922 result.record.time_duration.days +=
8923 to_days_result.days +
8925 std::round(to_days_result.nanoseconds / to_days_result.day_length);
8929 result.record.time_duration.hours =
result.record.time_duration.minutes =
8930 result.record.time_duration.seconds =
8931 result.record.time_duration.milliseconds =
8932 result.record.time_duration.microseconds =
8933 result.record.time_duration.nanoseconds = 0;
8939 fractional_seconds =
result.record.time_duration.nanoseconds * 1e-9 +
8940 result.record.time_duration.microseconds * 1e-6 +
8941 result.record.time_duration.milliseconds * 1e-3 +
8942 result.record.time_duration.seconds;
8952 DirectHandle<JSTemporalDuration> years_duration =
8953 CreateTemporalDuration(isolate,
8954 {duration.years, 0, 0, {0, 0, 0, 0, 0, 0, 0}})
8958 DirectHandle<Object> date_add;
8966 DirectHandle<JSTemporalPlainDate> years_later;
8968 isolate, years_later,
8970 isolate->factory()->undefined_value(), date_add),
8975 DirectHandle<JSTemporalDuration> years_months_weeks =
8976 CreateTemporalDuration(isolate, {duration.years,
8979 {0, 0, 0, 0, 0, 0, 0}})
8984 DirectHandle<JSTemporalPlainDate> years_months_weeks_later;
8986 isolate, years_months_weeks_later,
8988 isolate->factory()->undefined_value(), date_add),
8993 double months_weeks_in_days = DaysUntil(
8994 isolate, years_later, years_months_weeks_later, method_name);
9000 result.record.time_duration.days += months_weeks_in_days;
9004 DirectHandle<JSTemporalDuration> days_duration;
9006 isolate, days_duration,
9007 CreateTemporalDuration(
9009 {0, 0, 0, {
result.record.time_duration.days, 0, 0, 0, 0, 0, 0}}),
9014 DirectHandle<JSTemporalPlainDate> days_later;
9016 isolate, days_later,
9018 isolate->factory()->undefined_value(), date_add),
9022 DirectHandle<JSObject> until_options =
9023 factory->NewJSObjectWithNullProto();
9028 isolate, until_options, factory->largestUnit_string(),
9034 DirectHandle<JSTemporalDuration> time_passed;
9036 isolate, time_passed,
9045 result.record.years += years_passed;
9048 DirectHandle<Object> old_relative_to =
relative_to;
9052 years_duration = CreateTemporalDuration(
9053 isolate, {years_passed, 0, 0, {0, 0, 0, 0, 0, 0, 0}})
9058 DirectHandle<JSTemporalPlainDate> years_added;
9060 isolate, years_added,
9062 isolate->factory()->undefined_value(), date_add),
9067 DCHECK(IsJSTemporalPlainDate(*old_relative_to));
9069 double days_passed =
9074 result.record.time_duration.days -= days_passed;
9077 double sign =
result.record.time_duration.days < 0 ? -1 : 1;
9081 DirectHandle<JSTemporalDuration> one_year =
9082 CreateTemporalDuration(isolate, {
sign, 0, 0, {0, 0, 0, 0, 0, 0, 0}})
9086 MoveRelativeDateResult move_result;
9089 isolate, move_result,
9090 MoveRelativeDate(isolate,
calendar,
9096 double one_year_days = move_result.days;
9098 double fractional_years =
9100 result.record.time_duration.days / std::abs(one_year_days);
9103 result.record.years = RoundNumberToIncrement(isolate, fractional_years,
9106 result.remainder = fractional_years -
result.record.years;
9109 result.record.time_duration.days = 0;
9112 case Unit::kMonth: {
9115 DirectHandle<JSTemporalDuration> years_months =
9116 CreateTemporalDuration(
9118 {duration.years, duration.months, 0, {0, 0, 0, 0, 0, 0, 0}})
9122 DirectHandle<Object> date_add;
9130 DirectHandle<JSTemporalPlainDate> years_months_later;
9132 isolate, years_months_later,
9134 isolate->factory()->undefined_value(), date_add),
9139 DirectHandle<JSTemporalDuration> years_months_weeks =
9140 CreateTemporalDuration(isolate, {duration.years,
9143 {0, 0, 0, 0, 0, 0, 0}})
9148 DirectHandle<JSTemporalPlainDate> years_months_weeks_later;
9150 isolate, years_months_weeks_later,
9152 isolate->factory()->undefined_value(), date_add),
9157 double weeks_in_days = DaysUntil(isolate, years_months_later,
9158 years_months_weeks_later, method_name);
9164 result.record.time_duration.days += weeks_in_days;
9167 double sign =
result.record.time_duration.days < 0 ? -1 : 1;
9171 DirectHandle<JSTemporalDuration> one_month =
9172 CreateTemporalDuration(isolate, {0,
sign, 0, {0, 0, 0, 0, 0, 0, 0}})
9177 MoveRelativeDateResult move_result;
9180 isolate, move_result,
9181 MoveRelativeDate(isolate,
calendar,
9190 double one_month_days = move_result.days;
9193 while (std::abs(
result.record.time_duration.days) >=
9194 std::abs(one_month_days)) {
9198 result.record.time_duration.days -= one_month_days;
9203 isolate, move_result,
9204 MoveRelativeDate(isolate,
calendar,
9211 one_month_days = move_result.days;
9214 double fractional_months =
9216 result.record.time_duration.days / std::abs(one_month_days);
9219 result.record.months = RoundNumberToIncrement(isolate, fractional_months,
9222 result.remainder = fractional_months -
result.record.months;
9224 result.record.weeks =
result.record.time_duration.days = 0;
9229 double sign =
result.record.time_duration.days < 0 ? -1 : 1;
9232 DirectHandle<JSTemporalDuration> one_week =
9233 CreateTemporalDuration(isolate, {0, 0,
sign, {0, 0, 0, 0, 0, 0, 0}})
9237 MoveRelativeDateResult move_result;
9240 isolate, move_result,
9241 MoveRelativeDate(isolate,
calendar,
9250 double one_week_days = move_result.days;
9253 while (std::abs(
result.record.time_duration.days) >=
9254 std::abs(one_week_days)) {
9258 result.record.time_duration.days -= one_week_days;
9263 isolate, move_result,
9264 MoveRelativeDate(isolate,
calendar,
9271 one_week_days = move_result.days;
9275 double fractional_weeks =
9277 result.record.time_duration.days / std::abs(one_week_days);
9280 result.record.weeks = RoundNumberToIncrement(isolate, fractional_weeks,
9283 result.remainder = fractional_weeks -
result.record.weeks;
9285 result.record.time_duration.days = 0;
9290 double fractional_days =
result.record.time_duration.days;
9293 result.record.time_duration.days = RoundNumberToIncrement(
9297 result.remainder = fractional_days -
result.record.time_duration.days;
9303 double fractional_hours =
9304 (fractional_seconds / 60.0 + duration.time_duration.minutes) / 60.0 +
9305 duration.time_duration.hours;
9309 result.record.time_duration.hours = RoundNumberToIncrement(
9313 result.remainder = fractional_hours -
result.record.time_duration.hours;
9317 result.record.time_duration.minutes =
9318 result.record.time_duration.seconds =
9319 result.record.time_duration.milliseconds =
9320 result.record.time_duration.microseconds =
9321 result.record.time_duration.nanoseconds = 0;
9324 case Unit::kMinute: {
9326 double fractional_minutes =
9327 fractional_seconds / 60.0 + duration.time_duration.minutes;
9331 result.record.time_duration.minutes = RoundNumberToIncrement(
9336 fractional_minutes -
result.record.time_duration.minutes;
9339 result.record.time_duration.seconds =
9340 result.record.time_duration.milliseconds =
9341 result.record.time_duration.microseconds =
9342 result.record.time_duration.nanoseconds = 0;
9345 case Unit::kSecond: {
9348 result.record.time_duration.seconds = RoundNumberToIncrement(
9353 fractional_seconds -
result.record.time_duration.seconds;
9356 result.record.time_duration.milliseconds =
9357 result.record.time_duration.microseconds =
9358 result.record.time_duration.nanoseconds = 0;
9361 case Unit::kMillisecond: {
9364 double fractional_milliseconds =
9365 duration.time_duration.nanoseconds * 1e-6 +
9366 duration.time_duration.microseconds * 1e-3 +
9367 duration.time_duration.milliseconds;
9371 result.record.time_duration.milliseconds = RoundNumberToIncrement(
9376 fractional_milliseconds -
result.record.time_duration.milliseconds;
9379 result.record.time_duration.microseconds =
9380 result.record.time_duration.nanoseconds = 0;
9383 case Unit::kMicrosecond: {
9385 double fractional_microseconds =
9386 duration.time_duration.nanoseconds * 1e-3 +
9387 duration.time_duration.microseconds;
9391 result.record.time_duration.microseconds = RoundNumberToIncrement(
9396 fractional_microseconds -
result.record.time_duration.microseconds;
9399 result.record.time_duration.nanoseconds = 0;
9406 result.remainder =
result.record.time_duration.nanoseconds;
9410 result.record.time_duration.nanoseconds = RoundNumberToIncrement(
9415 result.remainder -=
result.record.time_duration.nanoseconds;
9421 isolate,
result.record, CreateDurationRecord(isolate,
result.record),
9427Maybe<DurationRecordWithRemainder> RoundDuration(Isolate* isolate,
9428 const DurationRecord& duration,
9431 const char* method_name) {
9434 isolate->factory()->undefined_value(), method_name);
9438struct StringPrecision {
9445Maybe<StringPrecision> ToSecondsStringPrecision(
9446 Isolate* isolate, DirectHandle<JSReceiver> normalized_options,
9447 const char* method_name);
9455 const char* method_name =
"Temporal.Duration.prototype.toString";
9464 ToSecondsStringPrecision(isolate, options, method_name),
9475 ToTemporalRoundingMode(isolate, options, RoundingMode::kTrunc,
9494 DurationRecordWithRemainder
result;
9506 return TemporalDurationToString(isolate,
result.record,
precision.precision);
9517 NewTypeError(MessageTemplate::kConstructorNotFunction,
9518 isolate->factory()->NewStringFromStaticChars(
9519 "Temporal.Calendar")));
9526 if (!IsBuiltinCalendar(isolate,
identifier)) {
9529 isolate, NewRangeError(MessageTemplate::kInvalidCalendar,
identifier));
9537int32_t ToISODayOfYear(
Isolate* isolate,
const DateRecord&
date) {
9547 isolate->date_cache()->DaysFromYearMonth(
date.year,
date.month - 1) -
9548 isolate->date_cache()->DaysFromYearMonth(
date.year, 0);
9551bool IsPlainDatePlainDateTimeOrPlainYearMonth(
9552 DirectHandle<Object> temporal_date_like) {
9553 return IsJSTemporalPlainDate(*temporal_date_like) ||
9554 IsJSTemporalPlainDateTime(*temporal_date_like) ||
9555 IsJSTemporalPlainYearMonth(*temporal_date_like);
9559int32_t ToISODayOfWeek(Isolate* isolate,
const DateRecord&
date) {
9567 int32_t epoch_days =
9568 isolate->date_cache()->DaysFromYearMonth(
date.year,
date.month - 1) +
9572 int32_t weekday = isolate->date_cache()->Weekday(epoch_days);
9584 return weekday == 0 ? 7 : weekday;
9588Maybe<DateRecord> RegulateISODate(Isolate* isolate, ShowOverflow overflow,
9589 const DateRecord&
date) {
9596 case ShowOverflow::kReject:
9599 if (!IsValidISODate(isolate,
date)) {
9608 case ShowOverflow::kConstrain:
9611 result.month = std::max(std::min(
result.month, 12), 1);
9615 std::max(std::min(
result.day,
9625Maybe<int32_t> RegulateISOYearMonth(Isolate* isolate, ShowOverflow overflow,
9631 case ShowOverflow::kConstrain:
9633 return Just(std::max(std::min(month, 12), 1));
9635 case ShowOverflow::kReject:
9637 if (month < 1 || 12 < month) {
9650Maybe<int32_t> ResolveISOMonth(Isolate* isolate,
9651 DirectHandle<JSReceiver> fields) {
9652 Factory* factory = isolate->factory();
9654 DirectHandle<Object> month_obj =
9658 DirectHandle<Object> month_code_obj =
9662 if (IsUndefined(*month_code_obj, isolate)) {
9664 if (IsUndefined(*month_obj, isolate)) {
9672 DCHECK(
IsSmi(*month_obj) || IsHeapNumber(*month_obj));
9676 DCHECK(IsString(*month_code_obj));
9677 DirectHandle<String> month_code;
9683 if (month_code->length() != 3) {
9686 NewRangeError(MessageTemplate::kPropertyValueOutOfRange,
9687 factory->monthCode_string()),
9696 if (!((m0 ==
'M') && ((m1 ==
'0' &&
'1' <= m2 && m2 <=
'9') ||
9697 (m1 ==
'1' &&
'0' <= m2 && m2 <=
'2')))) {
9700 NewRangeError(MessageTemplate::kPropertyValueOutOfRange,
9701 factory->monthCode_string()),
9705 10 *
static_cast<int32_t>(m1 -
'0') +
static_cast<int32_t>(m2 -
'0');
9712 if (!IsUndefined(*month_obj) &&
9717 NewRangeError(MessageTemplate::kPropertyValueOutOfRange,
9718 factory->month_string()),
9723 return Just(number_part);
9727Maybe<DateRecord> ISODateFromFields(Isolate* isolate,
9728 DirectHandle<JSReceiver> fields,
9729 DirectHandle<JSReceiver> options,
9730 const char* method_name) {
9731 Factory* factory = isolate->factory();
9736 DirectHandle<FixedArray> field_names =
9737 DayMonthMonthCodeYearInFixedArray(isolate);
9740 PrepareTemporalFields(isolate, fields, field_names,
9741 RequiredFields::kYearAndDay),
9746 isolate, overflow, ToTemporalOverflow(isolate, options, method_name),
9750 DirectHandle<Object> year_obj =
9757 DCHECK(
IsSmi(*year_obj) || IsHeapNumber(*year_obj));
9765 DirectHandle<Object> day_obj =
9772 DCHECK(
IsSmi(*day_obj) || IsHeapNumber(*day_obj));
9774 return RegulateISODate(
9781Maybe<DateRecord> AddISODate(Isolate* isolate,
const DateRecord&
date,
9782 const DateDurationRecord& duration,
9783 ShowOverflow overflow) {
9788 DCHECK(overflow == ShowOverflow::kConstrain ||
9789 overflow == ShowOverflow::kReject);
9791 DateRecord intermediate =
date;
9792 intermediate.year +=
static_cast<int32_t>(duration.years);
9793 intermediate.month +=
static_cast<int32_t>(duration.months);
9794 BalanceISOYearMonth(isolate, &intermediate.year, &intermediate.month);
9798 isolate, intermediate, RegulateISODate(isolate, overflow, intermediate),
9803 intermediate.day += duration.days + 7 * duration.weeks;
9805 return Just(BalanceISODate(isolate, intermediate));
9809Maybe<DateDurationRecord> DifferenceISODate(Isolate* isolate,
9810 const DateRecord& date1,
9811 const DateRecord& date2,
9813 const char* method_name) {
9822 case Unit::kMonth: {
9827 return DateDurationRecord::Create(isolate, 0, 0, 0, 0);
9833 DateRecord
start = date1;
9836 DateRecord
end = date2;
9843 AddISODate(isolate, date1, {
years, 0, 0, 0},
9844 ShowOverflow::kConstrain),
9849 int32_t mid_sign = -CompareISODate(mid, date2);
9852 if (mid_sign == 0) {
9856 return DateDurationRecord::Create(isolate,
years, 0, 0, 0);
9859 return DateDurationRecord::Create(isolate, 0,
years * 12, 0, 0);
9864 if (mid_sign !=
sign) {
9875 ShowOverflow::kConstrain),
9879 mid_sign = -CompareISODate(mid, date2);
9881 if (mid_sign == 0) {
9885 return DateDurationRecord::Create(isolate,
years,
months, 0, 0);
9888 return DateDurationRecord::Create(isolate, 0,
months +
years * 12, 0,
9892 if (mid_sign !=
sign) {
9907 ShowOverflow::kConstrain),
9911 mid_sign = -CompareISODate(mid, date2);
9916 if (mid.month ==
end.month) {
9921 }
else if (
sign < 0) {
9925 -mid.day - (ISODaysInMonth(isolate,
end.year,
end.month) -
end.day);
9930 end.day + (ISODaysInMonth(isolate, mid.year, mid.month) - mid.day);
9948 if (CompareISODate(date1, date2) < 0) {
9974 ToISODayOfYear(isolate,
greater) - ToISODayOfYear(isolate, smaller);
9977 for (int32_t year = smaller.year; year <
greater.year; year++) {
9980 days += ISODaysInYear(isolate, year);
9992 return DateDurationRecord::Create(isolate, 0, 0,
weeks *
sign,
10001Maybe<DateRecord> ISOYearMonthFromFields(Isolate* isolate,
10002 DirectHandle<JSReceiver> fields,
10003 DirectHandle<JSReceiver> options,
10004 const char* method_name) {
10005 Factory* factory = isolate->factory();
10009 DirectHandle<FixedArray> field_names = factory->NewFixedArray(3);
10010 field_names->set(0, ReadOnlyRoots(isolate).month_string());
10011 field_names->set(1, ReadOnlyRoots(isolate).monthCode_string());
10012 field_names->set(2, ReadOnlyRoots(isolate).year_string());
10015 PrepareTemporalFields(isolate, fields, field_names,
10016 RequiredFields::kNone),
10021 isolate, overflow, ToTemporalOverflow(isolate, options, method_name),
10025 DirectHandle<Object> year_obj =
10027 .ToHandleChecked();
10029 if (IsUndefined(*year_obj, isolate)) {
10041 isolate,
result.month, RegulateISOYearMonth(isolate, overflow, month),
10050int32_t ToISOWeekOfYear(Isolate* isolate,
const DateRecord&
date) {
10056 constexpr int32_t kWednesday = 3;
10058 constexpr int32_t kThursday = 4;
10060 constexpr int32_t kFriday = 5;
10062 constexpr int32_t kSaturday = 6;
10064 constexpr int32_t kDaysInWeek = 7;
10066 constexpr int32_t kMaxWeekNumber = 53;
10068 int32_t day_of_year = ToISODayOfYear(isolate,
date);
10070 int32_t day_of_week = ToISODayOfWeek(isolate,
date);
10074 (day_of_year + kDaysInWeek - day_of_week + kWednesday) / kDaysInWeek;
10079 int32_t day_of_jan_1st = ToISODayOfWeek(isolate, {
date.year, 1, 1});
10081 if (day_of_jan_1st == kFriday) {
10083 return kMaxWeekNumber;
10087 if (day_of_jan_1st == kSaturday && IsISOLeapYear(isolate,
date.year - 1)) {
10089 return kMaxWeekNumber;
10092 return kMaxWeekNumber - 1;
10095 if (week == kMaxWeekNumber) {
10097 int32_t days_in_year = ISODaysInYear(isolate,
date.year);
10099 int32_t days_later_in_year = days_in_year - day_of_year;
10101 int32_t days_after_thursday = kThursday - day_of_week;
10103 if (days_later_in_year < days_after_thursday) {
10119 const char* method_name =
"Temporal.Calendar.prototype.dateAdd";
10127 ToTemporalDate(isolate, date_obj, method_name));
10143 isolate, overflow, ToTemporalOverflow(isolate, options, method_name),
10150 TimeDurationRecord balance_result;
10152 isolate, balance_result,
10153 BalanceDuration(isolate, Unit::kDay,
10166 if (
calendar->calendar_index() == 0) {
10173 isolate, {
date->iso_year(),
date->iso_month(),
date->iso_day()},
10180#ifdef V8_INTL_SUPPORT
10203 if (!IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like)) {
10206 isolate, temporal_date_like,
10207 ToTemporalDate(isolate, temporal_date_like,
10208 "Temporal.Calendar.prototype.daysInYear"));
10213 if (IsJSTemporalPlainDate(*temporal_date_like)) {
10215 }
else if (IsJSTemporalPlainDateTime(*temporal_date_like)) {
10218 DCHECK(IsJSTemporalPlainYearMonth(*temporal_date_like));
10221 int32_t days_in_year = ISODaysInYear(isolate, year);
10237 if (!IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like)) {
10240 isolate, temporal_date_like,
10241 ToTemporalDate(isolate, temporal_date_like,
10242 "Temporal.Calendar.prototype.daysInMonth"));
10249 if (IsJSTemporalPlainDate(*temporal_date_like)) {
10252 }
else if (IsJSTemporalPlainDateTime(*temporal_date_like)) {
10256 DCHECK(IsJSTemporalPlainYearMonth(*temporal_date_like));
10276 if (!IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like)) {
10279 isolate, temporal_date_like,
10280 ToTemporalDate(isolate, temporal_date_like,
10281 "Temporal.Calendar.prototype.year"));
10286 if (IsJSTemporalPlainDate(*temporal_date_like)) {
10288 }
else if (IsJSTemporalPlainDateTime(*temporal_date_like)) {
10291 DCHECK(IsJSTemporalPlainYearMonth(*temporal_date_like));
10310 isolate, temporal_date,
10311 ToTemporalDate(isolate, temporal_date_like,
10312 "Temporal.Calendar.prototype.dayOfYear"));
10315 int32_t value = ToISODayOfYear(
10316 isolate, {temporal_date->iso_year(), temporal_date->iso_month(),
10317 temporal_date->iso_day()});
10332 isolate, temporal_date,
10333 ToTemporalDate(isolate, temporal_date_like,
10334 "Temporal.Calendar.prototype.dayOfWeek"));
10337 int32_t value = ToISODayOfWeek(
10338 isolate, {temporal_date->iso_year(), temporal_date->iso_month(),
10339 temporal_date->iso_day()});
10354 if (!IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like)) {
10357 isolate, temporal_date_like,
10358 ToTemporalDate(isolate, temporal_date_like,
10359 "Temporal.Calendar.prototype.monthsInYear"));
10363 int32_t months_in_year = 12;
10379 if (!IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like)) {
10382 isolate, temporal_date_like,
10383 ToTemporalDate(isolate, temporal_date_like,
10384 "Temporal.Calendar.prototype.inLeapYear"));
10389 if (IsJSTemporalPlainDate(*temporal_date_like)) {
10391 }
else if (IsJSTemporalPlainDateTime(*temporal_date_like)) {
10394 DCHECK(IsJSTemporalPlainYearMonth(*temporal_date_like));
10397 return isolate->factory()->ToBoolean(IsISOLeapYear(isolate, year));
10412 ToTemporalDate(isolate, temporal_date_like,
10413 "Temporal.Calendar.prototype.daysInWeek"));
10427 const char* method_name =
"Temporal.Calendar.prototype.dateFromFields";
10428 if (!IsJSReceiver(*fields_obj)) {
10430 NewTypeError(MessageTemplate::kCalledOnNonObject,
10431 isolate->factory()->NewStringFromAsciiChecked(
10440 if (
calendar->calendar_index() == 0) {
10445 ISODateFromFields(isolate, fields, options, method_name),
10474 if (
calendar->calendar_index() == 0) {
10476 return DefaultMergeFields(isolate, fields, additional_fields);
10478#ifdef V8_INTL_SUPPORT
10489 const char* method_name =
"Temporal.Calendar.prototype.dateUntil";
10497 ToTemporalDate(isolate, one_obj, method_name));
10501 ToTemporalDate(isolate, two_obj, method_name));
10512 GetTemporalUnit(isolate, options,
"largestUnit", UnitGroup::kDate,
10513 Unit::kAuto,
false, method_name),
10521 DateDurationRecord
result;
10524 DifferenceISODate(isolate,
10525 {
one->iso_year(),
one->iso_month(),
one->iso_day()},
10526 {two->iso_year(), two->iso_month(), two->iso_day()},
10532 return CreateTemporalDuration(isolate, {
result.years,
10535 {
result.days, 0, 0, 0, 0, 0, 0}})
10536 .ToHandleChecked();
10550 if (!(IsJSTemporalPlainDate(*temporal_date_like) ||
10551 IsJSTemporalPlainDateTime(*temporal_date_like) ||
10552 IsJSTemporalPlainMonthDay(*temporal_date_like))) {
10555 isolate, temporal_date_like,
10556 ToTemporalDate(isolate, temporal_date_like,
10557 "Temporal.Calendar.prototype.day"));
10562 if (IsJSTemporalPlainDate(*temporal_date_like)) {
10564 }
else if (IsJSTemporalPlainDateTime(*temporal_date_like)) {
10567 DCHECK(IsJSTemporalPlainMonthDay(*temporal_date_like));
10587 if (!(IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like) ||
10588 IsJSTemporalPlainMonthDay(*temporal_date_like))) {
10591 isolate, temporal_date_like,
10592 ToTemporalDate(isolate, temporal_date_like,
10593 "Temporal.Calendar.prototype.monthCode"));
10598 if (IsJSTemporalPlainDate(*temporal_date_like)) {
10600 }
else if (IsJSTemporalPlainDateTime(*temporal_date_like)) {
10602 }
else if (IsJSTemporalPlainMonthDay(*temporal_date_like)) {
10605 DCHECK(IsJSTemporalPlainYearMonth(*temporal_date_like));
10615 return builder.
Finish();
10624 if (IsJSTemporalPlainMonthDay(*temporal_date_like)) {
10632 if (!IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like)) {
10635 isolate, temporal_date_like,
10636 ToTemporalDate(isolate, temporal_date_like,
10637 "Temporal.Calendar.prototype.month"));
10642 if (IsJSTemporalPlainDate(*temporal_date_like)) {
10644 }
else if (IsJSTemporalPlainDateTime(*temporal_date_like)) {
10647 DCHECK(IsJSTemporalPlainYearMonth(*temporal_date_like));
10664 const char* method_name =
"Temporal.Calendar.prototype.monthDayFromFields";
10666 if (!IsJSReceiver(*fields_obj)) {
10668 NewTypeError(MessageTemplate::kCalledOnNonObject,
10669 isolate->factory()->NewStringFromAsciiChecked(
10678 if (
calendar->calendar_index() == 0) {
10682 ISOMonthDayFromFields(isolate, fields, options, method_name),
10702 const char* method_name =
"Temporal.Calendar.prototype.yearMonthFromFields";
10704 if (!IsJSReceiver(*fields_obj)) {
10706 NewTypeError(MessageTemplate::kCalledOnNonObject,
10707 isolate->factory()->NewStringFromAsciiChecked(
10716 if (
calendar->calendar_index() == 0) {
10720 ISOYearMonthFromFields(isolate, fields, options, method_name),
10731#ifdef V8_INTL_SUPPORT
10743 if (!IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like)) {
10746 isolate, temporal_date_like,
10747 ToTemporalDate(isolate, temporal_date_like,
10748 "Temporal.Calendar.prototype.era"));
10751 if (
calendar->calendar_index() == 0) {
10753 return isolate->factory()->undefined_value();
10761MaybeDirectHandle<Object> JSTemporalCalendar::EraYear(
10762 Isolate* isolate, DirectHandle<JSTemporalCalendar>
calendar,
10763 DirectHandle<Object> temporal_date_like) {
10771 if (!IsPlainDatePlainDateTimeOrPlainYearMonth(temporal_date_like)) {
10774 isolate, temporal_date_like,
10775 ToTemporalDate(isolate, temporal_date_like,
10776 "Temporal.Calendar.prototype.eraYear"));
10779 if (
calendar->calendar_index() == 0) {
10781 return isolate->factory()->undefined_value();
10805 isolate, temporal_date,
10806 ToTemporalDate(isolate, temporal_date_like,
10807 "Temporal.Calendar.prototype.weekOfYear"));
10810 int32_t value = ToISOWeekOfYear(
10811 isolate, {temporal_date->iso_year(), temporal_date->iso_month(),
10812 temporal_date->iso_day()});
10819 const char* method_name) {
10820 return CalendarIdentifier(isolate,
calendar->calendar_index());
10826 return SystemTimeZone(isolate);
10837 NewTypeError(MessageTemplate::kConstructorNotFunction,
10838 isolate->factory()->NewStringFromAsciiChecked(
10839 "Temporal.TimeZone")));
10848 if (IsValidTimeZoneNumericUTCOffsetString(isolate,
identifier)) {
10853 ParseTimeZoneOffsetString(isolate,
identifier),
10861 if (!IsValidTimeZoneName(isolate,
identifier)) {
10863 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidTimeZone,
10867 canonical = CanonicalizeTimeZoneName(isolate,
identifier);
10870 return CreateTemporalTimeZone(isolate, target,
new_target, canonical);
10882 return ToTemporalDateTime(isolate, item_obj,
10883 isolate->factory()->undefined_value(), method_name);
10892 const char* method_name =
"Temporal.TimeZone.prototype.getInstantFor";
10899 isolate, date_time,
10900 ToTemporalDateTime(isolate, date_time_obj, method_name));
10908 Disambiguation disambiguation;
10910 isolate, disambiguation,
10911 ToTemporalDisambiguation(isolate, options, method_name),
10916 return BuiltinTimeZoneGetInstantFor(isolate,
time_zone, date_time,
10917 disambiguation, method_name);
10922#ifdef V8_INTL_SUPPORT
10925 int32_t time_zone_index,
10928 return isolate->factory()->null_value();
10934DirectHandle<Object> GetIANATimeZoneNextTransition(
10935 Isolate* isolate, DirectHandle<BigInt>
nanoseconds,
10936 int32_t time_zone_index) {
10937 return GetIANATimeZoneTransition(isolate,
nanoseconds, time_zone_index,
10941DirectHandle<Object> GetIANATimeZonePreviousTransition(
10942 Isolate* isolate, DirectHandle<BigInt>
nanoseconds,
10943 int32_t time_zone_index) {
10944 return GetIANATimeZoneTransition(isolate,
nanoseconds, time_zone_index,
10948DirectHandle<Object> GetIANATimeZoneOffsetNanoseconds(
10949 Isolate* isolate, DirectHandle<BigInt>
nanoseconds,
10950 int32_t time_zone_index) {
10955 return isolate->factory()->NewNumberFromInt64(
10961DirectHandle<Object> GetIANATimeZoneNextTransition(Isolate* isolate,
10962 DirectHandle<BigInt>,
10964 return isolate->factory()->null_value();
10967DirectHandle<Object> GetIANATimeZonePreviousTransition(Isolate* isolate,
10968 DirectHandle<BigInt>,
10970 return isolate->factory()->null_value();
10972DirectHandle<Object> GetIANATimeZoneOffsetNanoseconds(Isolate* isolate,
10973 DirectHandle<BigInt>,
10974 int32_t time_zone_index) {
10983MaybeDirectHandle<JSTemporalPlainDateTime>
10988 const char* method_name =
"Temporal.TimeZone.prototype.getPlainDateTimeFor";
10995 isolate, instant, ToTemporalInstant(isolate, instant_obj, method_name));
11000 ToTemporalCalendarWithISODefault(isolate, calendar_like, method_name));
11022 isolate, starting_point,
11023 ToTemporalInstant(isolate, starting_point_obj, method_name));
11026 return isolate->factory()->null_value();
11032 iana_func(isolate,
direct_handle(starting_point->nanoseconds(), isolate),
11035 if (
IsNull(*transition_obj)) {
11036 return isolate->factory()->null_value();
11038 DCHECK(IsBigInt(*transition_obj));
11049 isolate,
time_zone, starting_point_obj,
11050 "Temporal.TimeZone.prototype.getNextTransition");
11057 isolate,
time_zone, starting_point_obj,
11058 "Temporal.TimeZone.prototype.getPreviousTransition");
11064 Isolate* isolate,
const DateTimeRecord& date_time) {
11065 Factory* factory = isolate->factory();
11068 GetEpochFromISOParts(isolate, date_time);
11073 if (!IsValidEpochNanoseconds(isolate, epoch_nanoseconds)) {
11079 .ToHandleChecked();
11081 fixed_array->set(0, *instant);
11086#ifdef V8_INTL_SUPPORT
11088 Isolate* isolate, int32_t time_zone_index,
11089 const DateTimeRecord& date_time) {
11090 Factory* factory = isolate->factory();
11096 DirectHandle<BigInt> nanoseconds_in_local_time =
11097 GetEpochFromISOParts(isolate, date_time);
11099 DirectHandleVector<BigInt> possible_offset =
11101 nanoseconds_in_local_time);
11103 int32_t array_length =
static_cast<int32_t
>(possible_offset.size());
11104 DirectHandle<FixedArray> fixed_array = factory->NewFixedArray(array_length);
11106 for (int32_t
i = 0;
i < array_length;
i++) {
11107 DirectHandle<BigInt> epoch_nanoseconds =
11109 .ToHandleChecked();
11112 if (!IsValidEpochNanoseconds(isolate, epoch_nanoseconds)) {
11116 DirectHandle<JSTemporalInstant> instant =
11118 .ToHandleChecked();
11120 fixed_array->set(
i, *(instant));
11124 return factory->NewJSArrayWithElements(fixed_array);
11130 Isolate* isolate, int32_t time_zone_index,
11131 const DateTimeRecord& date_time) {
11141 Factory* factory = isolate->factory();
11148 isolate, date_time,
11149 ToTemporalDateTime(isolate, date_time_obj,
11150 "Temporal.TimeZone.prototype.getPossibleInstantsFor"));
11151 DateTimeRecord date_time_record = {
11152 {date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
11153 {date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(),
11154 date_time->iso_millisecond(), date_time->iso_microsecond(),
11155 date_time->iso_nanosecond()}};
11164 GetEpochFromISOParts(isolate, date_time_record);
11167 epoch_nanoseconds =
11169 isolate, epoch_nanoseconds,
11171 .ToHandleChecked();
11178 if (!IsValidEpochNanoseconds(isolate, epoch_nanoseconds)) {
11186 .ToHandleChecked();
11189 fixed_array->set(0, *instant);
11203 isolate,
time_zone->time_zone_index(), date_time_record);
11218 ToTemporalInstant(isolate, instant_obj,
11219 "Temporal.TimeZone.prototype.getOffsetNanosecondsFor"));
11223 return isolate->factory()->NewNumberFromInt64(
11228 return GetIANATimeZoneOffsetNanoseconds(
11238 const char* method_name =
"Temporal.TimeZone.prototype.getOffsetStringFor";
11245 isolate, instant, ToTemporalInstant(isolate, instant_obj, method_name));
11247 return BuiltinTimeZoneGetOffsetStringFor(isolate,
time_zone, instant,
11254 const char* method_name) {
11259 DCHECK(is_offset() ==
false);
11267 static_cast<int64_t
>(offset_sub_milliseconds());
11271 this->set_offset_milliseconds(
static_cast<int32_t
>(ns / 1000000));
11272 this->set_offset_sub_milliseconds(
static_cast<int32_t
>(ns % 1000000));
11279#ifdef V8_INTL_SUPPORT
11282 return isolate->factory()->NewStringFromAsciiChecked(
id.c_str());
11285 return isolate->factory()->UTC_string();
11294 const char* method_name =
"Temporal.PlainDate";
11298 NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
11299 isolate->factory()->NewStringFromAsciiChecked(
11302#define TO_INT_THROW_ON_INFTY(name, T) \
11305 DirectHandle<Object> number_##name; \
11307 ASSIGN_RETURN_ON_EXCEPTION(isolate, number_##name, \
11308 ToIntegerThrowOnInfinity(isolate, name##_obj)); \
11309 name = NumberToInt32(*number_##name); \
11320 ToTemporalCalendarWithISODefault(isolate, calendar_like, method_name));
11323 return CreateTemporalDate(isolate, target,
new_target,
11324 {iso_year, iso_month, iso_day},
calendar);
11331 const char* method_name =
"Temporal.PlainDate.compare";
11335 ToTemporalDate(isolate, one_obj, method_name));
11339 ToTemporalDate(isolate, two_obj, method_name));
11344 CompareISODate({
one->iso_year(),
one->iso_month(),
one->iso_day()},
11345 {two->iso_year(), two->iso_month(), two->iso_day()})),
11353 Factory* factory = isolate->factory();
11361 ToTemporalDate(isolate, other_obj,
11362 "Temporal.PlainDate.prototype.equals"));
11364 if (temporal_date->iso_year() != other->iso_year()) {
11365 return factory->false_value();
11368 if (temporal_date->iso_month() != other->iso_month()) {
11369 return factory->false_value();
11372 if (temporal_date->iso_day() != other->iso_day()) {
11373 return factory->false_value();
11376 return CalendarEquals(isolate,
11385 const char* method_name =
"Temporal.PlainDate.prototype.withCalendar";
11396 return CreateTemporalDate(
11398 {temporal_date->iso_year(), temporal_date->iso_month(),
11399 temporal_date->iso_day()},
11409template <
typename T,
typename R,
11415 Factory* factory = isolate->factory();
11422 field_names->set(0, *f1);
11423 field_names->set(1, *f2);
11425 CalendarFields(isolate,
calendar, field_names));
11430 PrepareTemporalFields(isolate, t, field_names, RequiredFields::kNone));
11432 return from_fields(isolate,
calendar, fields,
11433 isolate->factory()->undefined_value());
11437MaybeDirectHandle<JSTemporalPlainYearMonth>
11441 YearMonthFromFields>(
isolate, temporal_date,
11442 isolate->factory()->monthCode_string(),
11443 isolate->factory()->year_string());
11450 MonthDayFromFields>(
isolate, temporal_date,
11451 isolate->factory()->day_string(),
11452 isolate->factory()->monthCode_string());
11463 if (IsUndefined(*temporal_time_obj)) {
11469 {{temporal_date->iso_year(), temporal_date->iso_month(),
11470 temporal_date->iso_day()},
11471 {0, 0, 0, 0, 0, 0}},
11477 isolate, temporal_time,
11479 "Temporal.PlainDate.prototype.toPlainDateTime"));
11488 {{temporal_date->iso_year(), temporal_date->iso_month(),
11489 temporal_date->iso_day()},
11490 {temporal_time->iso_hour(), temporal_time->iso_minute(),
11491 temporal_time->iso_second(), temporal_time->iso_millisecond(),
11492 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()}},
11503 Factory* factory = isolate->factory();
11509 if (IsJSTemporalPlainDate(*
object) || IsJSTemporalPlainDateTime(*
object) ||
11510 IsJSTemporalPlainMonthDay(*
object) || IsJSTemporalPlainTime(*
object) ||
11511 IsJSTemporalPlainYearMonth(*
object) ||
11512 IsJSTemporalZonedDateTime(*
object)) {
11518 DirectHandle<Object> calendar_property;
11520 isolate, calendar_property,
11524 if (!IsUndefined(*calendar_property)) {
11530 DirectHandle<Object> time_zone_property;
11532 isolate, time_zone_property,
11536 if (!IsUndefined(*time_zone_property)) {
11545MaybeDirectHandle<JSReceiver> CalendarMergeFields(
11546 Isolate* isolate, DirectHandle<JSReceiver>
calendar,
11547 DirectHandle<JSReceiver> fields,
11548 DirectHandle<JSReceiver> additional_fields) {
11550 DirectHandle<Object> merge_fields;
11552 isolate, merge_fields,
11554 isolate->factory()->mergeFields_string()));
11556 if (IsUndefined(*merge_fields)) {
11558 return DefaultMergeFields(isolate, fields, additional_fields);
11561 DirectHandle<Object>
args[] = {fields, additional_fields};
11562 DirectHandle<Object>
result;
11567 if (!IsJSReceiver(*
result)) {
11574template <typename T, MaybeDirectHandle<T> (*from_fields_func)(
11575 Isolate*, DirectHandle<JSReceiver>,
11576 DirectHandle<JSReceiver>, DirectHandle<Object>)>
11577MaybeDirectHandle<T> PlainDateOrYearMonthOrMonthDayWith(
11578 Isolate* isolate, DirectHandle<T> temporal,
11579 DirectHandle<Object> temporal_like_obj, DirectHandle<Object> options_obj,
11580 DirectHandle<FixedArray> field_names,
const char* method_name) {
11585 if (!IsJSReceiver(*temporal_like_obj)) {
11589 DirectHandle<JSReceiver> temporal_like =
Cast<JSReceiver>(temporal_like_obj);
11591 MAYBE_RETURN(RejectObjectWithCalendarOrTimeZone(isolate, temporal_like),
11592 DirectHandle<T>());
11595 DirectHandle<JSReceiver>
calendar(temporal->calendar(), isolate);
11599 CalendarFields(isolate,
calendar, field_names));
11602 DirectHandle<JSReceiver> partial_date;
11604 isolate, partial_date,
11605 PreparePartialTemporalFields(isolate, temporal_like, field_names));
11607 DirectHandle<JSReceiver>
options;
11611 DirectHandle<JSReceiver> fields;
11614 PrepareTemporalFields(isolate, temporal, field_names,
11615 RequiredFields::kNone));
11619 CalendarMergeFields(isolate,
calendar, fields, partial_date));
11622 PrepareTemporalFields(isolate, fields, field_names,
11623 RequiredFields::kNone));
11625 return from_fields_func(isolate,
calendar, fields, options);
11638 DayMonthMonthCodeYearInFixedArray(isolate);
11641 isolate, temporal_date, temporal_date_like_obj, options_obj, field_names,
11642 "Temporal.PlainDate.prototype.with");
11649 const char* method_name =
"Temporal.PlainDate.prototype.toZonedDateTime";
11650 Factory* factory = isolate->factory();
11657 if (IsJSReceiver(*item_obj)) {
11662 isolate, time_zone_like,
11665 if (IsUndefined(*time_zone_like)) {
11671 temporal_time_obj = factory->undefined_value();
11680 isolate, temporal_time_obj,
11690 temporal_time_obj = factory->undefined_value();
11695 if (IsUndefined(*temporal_time_obj)) {
11701 isolate, temporal_date_time,
11704 {{temporal_date->iso_year(), temporal_date->iso_month(),
11705 temporal_date->iso_day()},
11706 {0, 0, 0, 0, 0, 0}},
11713 isolate, temporal_time,
11723 isolate, temporal_date_time,
11726 {{temporal_date->iso_year(), temporal_date->iso_month(),
11727 temporal_date->iso_day()},
11728 {temporal_time->iso_hour(), temporal_time->iso_minute(),
11729 temporal_time->iso_second(), temporal_time->iso_millisecond(),
11730 temporal_time->iso_microsecond(),
11731 temporal_time->iso_nanosecond()}},
11739 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, temporal_date_time,
11740 Disambiguation::kCompatible, method_name));
11743 return CreateTemporalZonedDateTime(
11753 const char* method_name =
"Temporal.PlainDate.prototype.add";
11761 isolate, temporal_duration_like, method_name));
11769 return CalendarDateAdd(isolate,
11771 temporal_date, duration, options);
11779 const char* method_name =
"Temporal.PlainDate.prototype.subtract";
11787 isolate, temporal_duration_like, method_name));
11796 CreateNegatedTemporalDuration(isolate, duration).ToHandleChecked();
11800 return CalendarDateAdd(isolate,
11802 temporal_date, negated_duration, options);
11808 Isolate* isolate, TimePreposition operation,
11811 const char* method_name) {
11814 double sign = operation == TimePreposition::kSince ? -1 : 1;
11818 ToTemporalDate(isolate, other_obj, method_name));
11821 bool calendar_equals;
11823 isolate, calendar_equals,
11824 CalendarEqualsBool(isolate,
11828 if (!calendar_equals) {
11834 DifferenceSettings settings;
11837 GetDifferenceSettings(isolate, operation, options, UnitGroup::kDate,
11838 DisallowedUnitsInDifferenceSettings::kNone,
11839 Unit::kDay, Unit::kDay, method_name),
11840 DirectHandle<JSTemporalDuration>());
11843 DirectHandle<JSReceiver> until_options;
11845 isolate, until_options,
11846 MergeLargestUnitOption(isolate, settings.options, settings.largest_unit),
11847 DirectHandle<JSTemporalDuration>());
11850 DirectHandle<JSTemporalDuration>
result;
11853 CalendarDateUntil(isolate,
11855 temporal_date, other, until_options),
11856 DirectHandle<JSTemporalDuration>());
11859 if (settings.smallest_unit != Unit::kDay ||
11860 settings.rounding_increment != 1) {
11865 DurationRecordWithRemainder round_result;
11867 isolate, round_result,
11868 RoundDuration(isolate,
11873 settings.rounding_increment, settings.smallest_unit,
11874 settings.rounding_mode, temporal_date, method_name),
11875 DirectHandle<JSTemporalDuration>());
11879 round_result.record.years *=
sign;
11880 round_result.record.months *=
sign;
11881 round_result.record.weeks *=
sign;
11882 round_result.record.time_duration.days *=
sign;
11883 round_result.record.time_duration.hours =
11884 round_result.record.time_duration.minutes =
11885 round_result.record.time_duration.seconds =
11886 round_result.record.time_duration.milliseconds =
11887 round_result.record.time_duration.microseconds =
11888 round_result.record.time_duration.nanoseconds = 0;
11889 return CreateTemporalDuration(isolate, round_result.record)
11890 .ToHandleChecked();
11895 return CreateTemporalDuration(
11901 .ToHandleChecked();
11911 return DifferenceTemporalPlainDate(isolate, TimePreposition::kUntil,
handle,
11913 "Temporal.PlainDate.prototype.until");
11921 return DifferenceTemporalPlainDate(isolate, TimePreposition::kSince,
handle,
11923 "Temporal.PlainDate.prototype.since");
11930 const char* method_name =
"Temporal.Now.plainDate";
11934 SystemDateTime(isolate, temporal_time_zone_like,
11935 calendar_like, method_name));
11938 return CreateTemporalDate(
11940 {date_time->iso_year(), date_time->iso_month(),
11941 date_time->iso_day()},
11943 .ToHandleChecked();
11949 const char* method_name =
"Temporal.Now.plainDateISO";
11955 isolate, date_time,
11956 SystemDateTime(isolate, temporal_time_zone_like,
calendar, method_name));
11959 return CreateTemporalDate(
11961 {date_time->iso_year(), date_time->iso_month(),
11962 date_time->iso_day()},
11964 .ToHandleChecked();
11971 const char* method_name =
"Temporal.PlainDate.from";
11978 if (IsJSTemporalPlainDate(*item)) {
11981 isolate, ToTemporalOverflow(isolate, options, method_name),
11986 return CreateTemporalDate(
11987 isolate, {
date->iso_year(),
date->iso_month(),
date->iso_day()},
11991 return ToTemporalDate(isolate, item, options, method_name);
11994#define DEFINE_INT_FIELD(obj, str, field, item) \
11995 CHECK(JSReceiver::CreateDataProperty( \
11996 isolate, obj, factory->str##_string(), \
11997 DirectHandle<Smi>(Smi::FromInt(item->field()), isolate), \
11998 Just(kThrowOnError)) \
12004 Factory* factory = isolate->factory();
12010 isolate->factory()->NewJSObject(isolate->object_function());
12014 isolate, fields, factory->calendar_string(),
12038 return TemporalDateToString(isolate, temporal_date, ShowCalendar::kAuto);
12046 const char* method_name) {
12050 isolate, options,
"calendarName", method_name,
12051 {
"auto",
"always",
"never"},
12052 {ShowCalendar::kAuto, ShowCalendar::kAlways, ShowCalendar::kNever},
12053 ShowCalendar::kAuto);
12056template <typename T, MaybeDirectHandle<String> (*
F)(Isolate*, DirectHandle<T>,
12058MaybeDirectHandle<String> TemporalToString(Isolate* isolate,
12059 DirectHandle<T> temporal,
12060 DirectHandle<Object> options_obj,
12061 const char* method_name) {
12066 DirectHandle<JSReceiver>
options;
12070 ShowCalendar show_calendar;
12072 isolate, show_calendar,
12073 ToShowCalendarOption(isolate, options, method_name),
12074 DirectHandle<String>());
12076 return F(isolate, temporal, show_calendar);
12084 return TemporalToString<JSTemporalPlainDate, TemporalDateToString>(
12085 isolate, temporal_date, options,
"Temporal.PlainDate.prototype.toString");
12092#ifdef V8_INTL_SUPPORT
12094 isolate, temporal_date, locales, options,
12095 "Temporal.PlainDate.prototype.toLocaleString");
12097 return TemporalDateToString(isolate, temporal_date, ShowCalendar::kAuto);
12110 const char* method_name =
"Temporal.PlainDateTime";
12114 NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
12115 isolate->factory()->NewStringFromAsciiChecked(
12133 ToTemporalCalendarWithISODefault(isolate, calendar_like, method_name));
12137 return CreateTemporalDateTime(
12139 {{iso_year, iso_month, iso_day},
12150 const char* method_name) {
12154 TimeRecord time_result;
12156 isolate, time_result, ToTemporalTimeRecord(isolate, fields, method_name),
12162 isolate, temporal_date,
12163 DateFromFields(isolate,
calendar, fields, options),
12169 isolate, overflow, ToTemporalOverflow(isolate, options, method_name),
12176 isolate, time_result,
12187 {temporal_date->iso_year(), temporal_date->iso_month(),
12188 temporal_date->iso_day()},
12194Maybe<DateTimeRecordWithCalendar> ParseTemporalDateTimeString(
12195 Isolate* isolate, DirectHandle<String> iso_string) {
12200 std::optional<ParsedISO8601Result> parsed =
12201 TemporalParser::ParseTemporalDateTimeString(isolate, iso_string);
12202 if (!parsed.has_value()) {
12210 if (parsed->utc_designator) {
12219 return ParseISODateTime(isolate, iso_string, *parsed);
12223MaybeDirectHandle<JSTemporalPlainDateTime> ToTemporalDateTime(
12224 Isolate* isolate, DirectHandle<Object> item_obj,
12225 DirectHandle<Object> options,
const char* method_name) {
12228 DCHECK(IsJSReceiver(*options) || IsUndefined(*options));
12230 DirectHandle<JSReceiver>
calendar;
12231 temporal::DateTimeRecord
result;
12233 if (IsJSReceiver(*item_obj)) {
12237 if (IsJSTemporalPlainDateTime(*item)) {
12242 if (IsJSTemporalZonedDateTime(*item)) {
12245 isolate, ToTemporalOverflow(isolate, options, method_name),
12246 DirectHandle<JSTemporalPlainDateTime>());
12249 DirectHandle<JSTemporalInstant> instant =
12251 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
12252 .ToHandleChecked();
12257 isolate,
direct_handle(zoned_date_time->time_zone(), isolate),
12258 instant,
direct_handle(zoned_date_time->calendar(), isolate),
12262 if (IsJSTemporalPlainDate(*item)) {
12265 isolate, ToTemporalOverflow(isolate, options, method_name),
12266 DirectHandle<JSTemporalPlainDateTime>());
12273 {{
date->iso_year(),
date->iso_month(),
date->iso_day()},
12274 {0, 0, 0, 0, 0, 0}},
12280 GetTemporalCalendarWithISODefault(isolate, item, method_name));
12284 DirectHandle<FixedArray> field_names = All10UnitsInFixedArray(isolate);
12286 CalendarFields(isolate,
calendar, field_names));
12289 DirectHandle<JSReceiver> fields;
12291 PrepareTemporalFields(isolate, item, field_names,
12292 RequiredFields::kNone));
12297 InterpretTemporalDateTimeFields(isolate,
calendar, fields, options,
12299 DirectHandle<JSTemporalPlainDateTime>());
12304 isolate, ToTemporalOverflow(isolate, options, method_name),
12305 DirectHandle<JSTemporalPlainDateTime>());
12308 DirectHandle<String>
string;
12312 DateTimeRecordWithCalendar parsed_result;
12314 isolate, parsed_result, ParseTemporalDateTimeString(isolate,
string),
12315 DirectHandle<JSTemporalPlainDateTime>());
12316 result = {parsed_result.date, parsed_result.time};
12328 ToTemporalCalendarWithISODefault(isolate, parsed_result.calendar,
12345 const char* method_name =
"Temporal.PlainDateTime.from";
12352 if (IsJSTemporalPlainDateTime(*item)) {
12355 isolate, ToTemporalOverflow(isolate, options, method_name),
12364 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
12365 {date_time->iso_hour(), date_time->iso_minute(),
12366 date_time->iso_second(), date_time->iso_millisecond(),
12367 date_time->iso_microsecond(), date_time->iso_nanosecond()}},
12371 return ToTemporalDateTime(isolate, item, options, method_name);
12378 const char* method_name =
"Temporal.PlainDateTime.compare";
12382 ToTemporalDateTime(isolate, one_obj, method_name));
12386 ToTemporalDateTime(isolate, two_obj, method_name));
12396 {
one->iso_year(),
one->iso_month(),
one->iso_day()},
12397 {
one->iso_hour(),
one->iso_minute(),
one->iso_second(),
12398 one->iso_millisecond(),
one->iso_microsecond(),
12399 one->iso_nanosecond()},
12402 {two->iso_year(), two->iso_month(), two->iso_day()},
12403 {two->iso_hour(), two->iso_minute(), two->iso_second(),
12404 two->iso_millisecond(), two->iso_microsecond(),
12405 two->iso_nanosecond()},
12421 ToTemporalDateTime(isolate, other_obj,
12422 "Temporal.PlainDateTime.prototype.equals"));
12431 int32_t
result = CompareISODateTime(
12433 {date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
12434 {date_time->iso_hour(), date_time->iso_minute(),
12435 date_time->iso_second(), date_time->iso_millisecond(),
12436 date_time->iso_microsecond(), date_time->iso_nanosecond()},
12439 {other->iso_year(), other->iso_month(), other->iso_day()},
12440 {other->iso_hour(), other->iso_minute(), other->iso_second(),
12441 other->iso_millisecond(), other->iso_microsecond(),
12442 other->iso_nanosecond()},
12445 if (
result != 0)
return isolate->factory()->false_value();
12447 return CalendarEquals(isolate,
direct_handle(date_time->calendar(), isolate),
12456 const char* method_name =
"Temporal.PlainDateTime.prototype.with";
12461 if (!IsJSReceiver(*temporal_date_time_like_obj)) {
12469 RejectObjectWithCalendarOrTimeZone(isolate, temporal_date_time_like),
12478 CalendarFields(isolate,
calendar, field_names));
12484 isolate, partial_date_time,
12485 PreparePartialTemporalFields(isolate, temporal_date_time_like,
12496 PrepareTemporalFields(isolate, date_time, field_names,
12497 RequiredFields::kNone));
12502 CalendarMergeFields(isolate,
calendar, fields, partial_date_time));
12505 PrepareTemporalFields(isolate, fields, field_names,
12506 RequiredFields::kNone));
12512 InterpretTemporalDateTimeFields(isolate,
calendar, fields, options,
12539 if (IsUndefined(*plain_time_like)) {
12545 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
12546 {0, 0, 0, 0, 0, 0}},
12552 isolate, plain_time,
12554 isolate, plain_time_like,
12555 "Temporal.PlainDateTime.prototype.withPlainTime"));
12563 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
12564 {plain_time->iso_hour(), plain_time->iso_minute(),
12565 plain_time->iso_second(), plain_time->iso_millisecond(),
12566 plain_time->iso_microsecond(), plain_time->iso_nanosecond()}},
12583 isolate, calendar_like,
12584 "Temporal.PlainDateTime.prototype.withCalendar"));
12593 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
12594 {date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(),
12595 date_time->iso_millisecond(), date_time->iso_microsecond(),
12596 date_time->iso_nanosecond()}},
12605 YearMonthFromFields>(
isolate, date_time,
12606 isolate->factory()->monthCode_string(),
12607 isolate->factory()->year_string());
12615 MonthDayFromFields>(
isolate, date_time,
12616 isolate->factory()->day_string(),
12617 isolate->factory()->monthCode_string());
12626 const char* method_name =
"Temporal.PlainDateTime.prototype.toZonedDateTime";
12641 Disambiguation disambiguation;
12643 isolate, disambiguation,
12644 ToTemporalDisambiguation(isolate, options, method_name),
12652 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, date_time,
12653 disambiguation, method_name));
12657 return CreateTemporalZonedDateTime(
12668 Factory* factory = isolate->factory();
12670 if (
one.is_identical_to(two))
return two;
12685 if (
String::Equals(isolate, calendar_one, factory->iso8601_string())) {
12689 if (
String::Equals(isolate, calendar_two, factory->iso8601_string())) {
12699MaybeDirectHandle<JSTemporalPlainDateTime>
12709 isolate, plain_date,
12710 ToTemporalDate(isolate, temporal_date_like,
12711 "Temporal.PlainDateTime.prototype.withPlainDate"));
12717 ConsolidateCalendars(isolate,
12727 {{plain_date->iso_year(), plain_date->iso_month(), plain_date->iso_day()},
12728 {date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(),
12729 date_time->iso_millisecond(), date_time->iso_microsecond(),
12730 date_time->iso_nanosecond()}},
12736 Isolate* isolate,
const DateTimeRecord& date_time,
12738 ShowCalendar show_calendar) {
12743 PadISOYear(&builder, date_time.date.year);
12746 builder.AppendCharacter(
'-');
12747 ToZeroPaddedDecimalString(&builder, date_time.date.month, 2);
12750 builder.AppendCharacter(
'-');
12751 ToZeroPaddedDecimalString(&builder, date_time.date.day, 2);
12753 builder.AppendCharacter(
'T');
12754 ToZeroPaddedDecimalString(&builder, date_time.time.hour, 2);
12757 builder.AppendCharacter(
':');
12758 ToZeroPaddedDecimalString(&builder, date_time.time.minute, 2);
12762 FormatSecondsStringPart(
12763 &builder, date_time.time.second, date_time.time.millisecond,
12764 date_time.time.microsecond, date_time.time.nanosecond,
precision);
12769 isolate, calendar_string,
12770 MaybeFormatCalendarAnnotation(isolate,
calendar, show_calendar));
12775 builder.AppendString(calendar_string);
12776 return builder.Finish().ToHandleChecked();
12783 return TemporalDateTimeToString(
12785 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
12786 {date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(),
12787 date_time->iso_millisecond(), date_time->iso_microsecond(),
12788 date_time->iso_nanosecond()}},
12790 Precision::kAuto, ShowCalendar::kAuto);
12797#ifdef V8_INTL_SUPPORT
12799 isolate, date_time, locales, options,
12800 "Temporal.PlainDateTime.prototype.toLocaleString");
12802 return TemporalDateTimeToString(
12804 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
12805 {date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(),
12806 date_time->iso_millisecond(), date_time->iso_microsecond(),
12807 date_time->iso_nanosecond()}},
12809 Precision::kAuto, ShowCalendar::kAuto);
12815constexpr double kNsPerDay = 8.64e13;
12817DateTimeRecord RoundTime(
12821 double day_length_ns = kNsPerDay);
12824DateTimeRecord RoundISODateTime(
12828 double day_length_ns = kNsPerDay) {
12834 DCHECK(ISODateTimeWithinLimits(isolate, date_time));
12838 DateTimeRecord rounded_time = RoundTime(isolate, date_time.time,
increment,
12842 rounded_time.date.year = date_time.date.year;
12843 rounded_time.date.month = date_time.date.month;
12844 rounded_time.date.day += date_time.date.day;
12845 DateRecord balance_result = BalanceISODate(isolate, rounded_time.date);
12853 return {balance_result, rounded_time.time};
12862 const char* method_name =
"Temporal.PlainDateTime.prototype.toString";
12875 ToSecondsStringPrecision(isolate, options, method_name),
12882 ToTemporalRoundingMode(isolate, options, RoundingMode::kTrunc,
12887 ShowCalendar show_calendar;
12889 isolate, show_calendar,
12890 ToShowCalendarOption(isolate, options, method_name),
12899 DateTimeRecord
result = RoundISODateTime(
12901 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
12902 {date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(),
12903 date_time->iso_millisecond(), date_time->iso_microsecond(),
12904 date_time->iso_nanosecond()}},
12910 return TemporalDateTimeToString(isolate,
result,
12919 const char* method_name =
"Temporal.Now.plainDateTime";
12921 return SystemDateTime(isolate, temporal_time_zone_like, calendar_like,
12928 const char* method_name =
"Temporal.Now.plainDateTimeISO";
12932 return SystemDateTime(isolate, temporal_time_zone_like,
calendar,
12947 maximum.defined =
true;
12952 maximum = MaximumTemporalDurationRoundingIncrement(
smallest_unit);
12954 DCHECK(maximum.defined);
12957 return ToTemporalRoundingIncrement(isolate, normalized_option, maximum.value,
12958 maximum.defined,
false);
12967 const char* method_name =
"Temporal.PlainDateTime.prototype.round";
12968 Factory* factory = isolate->factory();
12973 if (IsUndefined(*round_to_obj)) {
12980 if (IsString(*round_to_obj)) {
12988 factory->smallestUnit_string(),
13004 GetTemporalUnit(isolate, round_to,
"smallestUnit", UnitGroup::kTime,
13005 Unit::kDay,
true, method_name),
13012 ToTemporalRoundingMode(isolate, round_to, RoundingMode::kHalfExpand,
13021 ToTemporalDateTimeRoundingIncrement(isolate, round_to,
smallest_unit),
13029 DateTimeRecord
result = RoundISODateTime(
13031 {{date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
13032 {date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(),
13033 date_time->iso_millisecond(), date_time->iso_microsecond(),
13034 date_time->iso_nanosecond()}},
13048AddDurationToOrSubtractDurationFromPlainDateTime(
13049 Isolate* isolate, Arithmetic operation,
13054 double sign = operation == Arithmetic::kSubtract ? -1.0 : 1.0;
13063 TimeDurationRecord& time_duration = duration.
time_duration;
13080 AddDateTime(isolate,
13081 {{date_time->iso_year(), date_time->iso_month(),
13082 date_time->iso_day()},
13083 {date_time->iso_hour(), date_time->iso_minute(),
13084 date_time->iso_second(), date_time->iso_millisecond(),
13085 date_time->iso_microsecond(), date_time->iso_nanosecond()}},
13090 {
sign * time_duration.days,
sign * time_duration.hours,
13091 sign * time_duration.minutes,
sign * time_duration.seconds,
13092 sign * time_duration.milliseconds,
13093 sign * time_duration.microseconds,
13094 sign * time_duration.nanoseconds}},
13096 DirectHandle<JSTemporalPlainDateTime>());
13119 return AddDurationToOrSubtractDurationFromPlainDateTime(
13120 isolate, Arithmetic::kAdd, date_time, temporal_duration_like, options,
13121 "Temporal.PlainDateTime.prototype.add");
13128 return AddDurationToOrSubtractDurationFromPlainDateTime(
13129 isolate, Arithmetic::kSubtract, date_time, temporal_duration_like,
13130 options,
"Temporal.PlainDateTime.prototype.subtract");
13137 Isolate* isolate, TimePreposition operation,
13140 const char* method_name) {
13143 double sign = operation == TimePreposition::kSince ? -1 : 1;
13147 isolate, other, ToTemporalDateTime(isolate, other_obj, method_name));
13150 bool calendar_equals;
13152 isolate, calendar_equals,
13153 CalendarEqualsBool(isolate,
direct_handle(date_time->calendar(), isolate),
13156 if (!calendar_equals) {
13161 DifferenceSettings settings;
13164 GetDifferenceSettings(isolate, operation, options, UnitGroup::kDateTime,
13165 DisallowedUnitsInDifferenceSettings::kNone,
13166 Unit::kNanosecond, Unit::kDay, method_name),
13167 DirectHandle<JSTemporalDuration>());
13177 DurationRecord diff;
13180 DifferenceISODateTime(
13182 {{date_time->iso_year(), date_time->iso_month(),
13183 date_time->iso_day()},
13184 {date_time->iso_hour(), date_time->iso_minute(),
13185 date_time->iso_second(), date_time->iso_millisecond(),
13186 date_time->iso_microsecond(), date_time->iso_nanosecond()}},
13187 {{other->iso_year(), other->iso_month(), other->iso_day()},
13188 {other->iso_hour(), other->iso_minute(), other->iso_second(),
13189 other->iso_millisecond(), other->iso_microsecond(),
13190 other->iso_nanosecond()}},
13191 direct_handle(date_time->calendar(), isolate), settings.largest_unit,
13192 settings.options, method_name),
13193 DirectHandle<JSTemporalDuration>());
13199 CreateTemporalDate(
13201 {date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
13203 DirectHandle<JSTemporalDuration>());
13210 DurationRecordWithRemainder round_result;
13212 isolate, round_result,
13213 RoundDuration(isolate, diff, settings.rounding_increment,
13214 settings.smallest_unit, settings.rounding_mode,
relative_to,
13216 DirectHandle<JSTemporalDuration>());
13222 isolate, round_result.record.time_duration,
13223 BalanceDuration(isolate, settings.largest_unit,
13224 round_result.record.time_duration, method_name),
13225 DirectHandle<JSTemporalDuration>());
13231 return CreateTemporalDuration(
13232 isolate, {
sign * round_result.record.years,
13233 sign * round_result.record.months,
13234 sign * round_result.record.weeks,
13235 {
sign * round_result.record.time_duration.days,
13236 sign * round_result.record.time_duration.hours,
13237 sign * round_result.record.time_duration.minutes,
13238 sign * round_result.record.time_duration.seconds,
13239 sign * round_result.record.time_duration.milliseconds,
13240 sign * round_result.record.time_duration.microseconds,
13241 sign * round_result.record.time_duration.nanoseconds}})
13242 .ToHandleChecked();
13252 return DifferenceTemporalPlainDateTime(
13253 isolate, TimePreposition::kUntil,
handle, other, options,
13254 "Temporal.PlainDateTime.prototype.until");
13262 return DifferenceTemporalPlainDateTime(
13263 isolate, TimePreposition::kSince,
handle, other, options,
13264 "Temporal.PlainDateTime.prototype.since");
13270 Factory* factory = isolate->factory();
13276 isolate->factory()->NewJSObject(isolate->object_function());
13280 isolate, fields, factory->calendar_string(),
13323 return CreateTemporalDate(
13325 {date_time->iso_year(), date_time->iso_month(), date_time->iso_day()},
13339 return CreateTemporalTime(
13340 isolate, {date_time->iso_hour(), date_time->iso_minute(),
13341 date_time->iso_second(), date_time->iso_millisecond(),
13342 date_time->iso_microsecond(), date_time->iso_nanosecond()});
13351 const char* method_name =
"Temporal.PlainMonthDay";
13355 NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
13356 isolate->factory()->NewStringFromAsciiChecked(
13368 ToTemporalCalendarWithISODefault(isolate, calendar_like, method_name));
13374 int32_t ref = 1972;
13375 if (!IsUndefined(*reference_iso_year_obj)) {
13377 ref = reference_iso_year;
13381 return CreateTemporalMonthDay(isolate, target,
new_target, iso_month, iso_day,
13395 std::optional<ParsedISO8601Result> parsed =
13396 TemporalParser::ParseTemporalMonthDayString(isolate, iso_string);
13397 if (!parsed.has_value()) {
13404 if (parsed->utc_designator) {
13412 DateTimeRecordWithCalendar
result;
13414 isolate,
result, ParseISODateTime(isolate, iso_string, *parsed),
13422 DateRecordWithCalendar ret({
result.date,
result.calendar});
13427MaybeDirectHandle<JSTemporalPlainMonthDay> ToTemporalMonthDay(
13428 Isolate* isolate, DirectHandle<Object> item_obj,
13429 DirectHandle<Object> options,
const char* method_name) {
13432 Factory* factory = isolate->factory();
13434 DCHECK(IsJSReceiver(*options) || IsUndefined(*options));
13437 constexpr int32_t kReferenceIsoYear = 1972;
13439 if (IsJSReceiver(*item_obj)) {
13443 if (IsJSTemporalPlainMonthDay(*item_obj)) {
13446 bool calendar_absent =
false;
13453 DirectHandle<JSReceiver>
calendar;
13454 if (IsJSTemporalPlainDate(*item_obj)) {
13457 }
else if (IsJSTemporalPlainDateTime(*item_obj)) {
13460 }
else if (IsJSTemporalPlainTime(*item_obj)) {
13463 }
else if (IsJSTemporalPlainYearMonth(*item_obj)) {
13466 }
else if (IsJSTemporalZonedDateTime(*item_obj)) {
13472 DirectHandle<Object> calendar_obj;
13474 isolate, calendar_obj,
13477 if (IsUndefined(*calendar_obj)) {
13479 calendar_absent =
true;
13484 ToTemporalCalendarWithISODefault(isolate, calendar_obj, method_name));
13488 DirectHandle<FixedArray> field_names =
13489 DayMonthMonthCodeYearInFixedArray(isolate);
13491 CalendarFields(isolate,
calendar, field_names));
13493 DirectHandle<JSReceiver> fields;
13495 PrepareTemporalFields(isolate, item, field_names,
13496 RequiredFields::kNone));
13498 DirectHandle<Object> month;
13502 DirectHandle<JSTemporalPlainMonthDay>());
13504 DirectHandle<Object> month_code;
13506 isolate, month_code,
13508 DirectHandle<JSTemporalPlainMonthDay>());
13510 DirectHandle<Object> year;
13514 DirectHandle<JSTemporalPlainMonthDay>());
13517 if (calendar_absent && !IsUndefined(*month) && IsUndefined(*month_code) &&
13518 IsUndefined(*year)) {
13522 isolate, fields, factory->year_string(),
13528 return MonthDayFromFields(isolate,
calendar, fields, options);
13532 isolate, ToTemporalOverflow(isolate, options, method_name),
13533 DirectHandle<JSTemporalPlainMonthDay>());
13536 DirectHandle<String>
string;
13541 DateRecordWithCalendar
result;
13543 isolate,
result, ParseTemporalMonthDayString(isolate,
string),
13544 DirectHandle<JSTemporalPlainMonthDay>());
13547 DirectHandle<JSReceiver>
calendar;
13550 ToTemporalCalendarWithISODefault(isolate,
result.calendar, method_name));
13557 return CreateTemporalMonthDay(isolate,
result.date.month,
result.date.day,
13561 DirectHandle<JSTemporalPlainMonthDay> created_result;
13565 isolate, created_result,
13566 CreateTemporalMonthDay(isolate,
result.date.month,
result.date.day,
13572 return MonthDayFromFields(isolate,
calendar, created_result);
13575MaybeDirectHandle<JSTemporalPlainMonthDay> ToTemporalMonthDay(
13576 Isolate* isolate, DirectHandle<Object> item_obj,
const char* method_name) {
13578 return ToTemporalMonthDay(isolate, item_obj,
13579 isolate->factory()->undefined_value(), method_name);
13588 const char* method_name =
"Temporal.PlainMonthDay.from";
13595 if (IsJSTemporalPlainMonthDay(*item)) {
13598 isolate, ToTemporalOverflow(isolate, options, method_name),
13603 return CreateTemporalMonthDay(
13604 isolate, month_day->iso_month(), month_day->iso_day(),
13605 direct_handle(month_day->calendar(), isolate), month_day->iso_year());
13608 return ToTemporalMonthDay(isolate, item, options, method_name);
13622 ToTemporalMonthDay(isolate, other_obj,
13623 "Temporal.PlainMonthDay.prototype.equals"));
13625 if (month_day->iso_month() != other->iso_month())
13626 return isolate->factory()->false_value();
13628 if (month_day->iso_day() != other->iso_day())
13629 return isolate->factory()->false_value();
13631 if (month_day->iso_year() != other->iso_year())
13632 return isolate->factory()->false_value();
13634 return CalendarEquals(
13647 DayMonthMonthCodeYearInFixedArray(isolate);
13649 MonthDayFromFields>(
13650 isolate, temporal_month_day, temporal_month_day_like_obj, options_obj,
13651 field_names,
"Temporal.PlainMonthDay.prototype.with");
13657template <
typename T>
13663 Factory* factory = isolate->factory();
13668 if (!IsJSReceiver(*item_obj)) {
13674 DirectHandle<JSReceiver>
calendar(temporal->calendar(), isolate);
13677 DirectHandle<FixedArray> receiver_field_names = factory->
NewFixedArray(2);
13678 receiver_field_names->set(0, *receiver_field_name_1);
13679 receiver_field_names->set(1, *receiver_field_name_2);
13681 isolate, receiver_field_names,
13682 CalendarFields(isolate,
calendar, receiver_field_names));
13684 DirectHandle<JSReceiver> fields;
13687 PrepareTemporalFields(isolate, temporal, receiver_field_names,
13688 RequiredFields::kNone));
13690 DirectHandle<FixedArray> input_field_names = factory->
NewFixedArray(1);
13691 input_field_names->set(0, *input_field_name);
13693 isolate, input_field_names,
13694 CalendarFields(isolate,
calendar, input_field_names));
13696 DirectHandle<JSReceiver> input_fields;
13698 isolate, input_fields,
13699 PrepareTemporalFields(isolate, item, input_field_names,
13700 RequiredFields::kNone));
13703 DirectHandle<JSReceiver> merged_fields;
13705 isolate, merged_fields,
13706 CalendarMergeFields(isolate,
calendar, fields, input_fields));
13710 DirectHandle<FixedArray> merged_field_names = factory->
NewFixedArray(
13711 receiver_field_names->length() + input_field_names->length());
13713 for (
int i = 0;
i < receiver_field_names->
length();
i++) {
13714 DirectHandle<Object> field(receiver_field_names->get(
i), isolate);
13715 DCHECK(IsString(*field));
13717 if (!added->Has(isolate,
string)) {
13718 merged_field_names->set(added->NumberOfElements(), *field);
13722 for (
int i = 0;
i < input_field_names->
length();
i++) {
13723 DirectHandle<Object> field(input_field_names->get(
i), isolate);
13724 DCHECK(IsString(*field));
13726 if (!added->Has(isolate,
string)) {
13727 merged_field_names->set(added->NumberOfElements(), *field);
13732 added->NumberOfElements());
13737 isolate, merged_fields,
13738 PrepareTemporalFields(isolate, merged_fields, merged_field_names,
13739 RequiredFields::kNone));
13744 isolate, options, factory->overflow_string(),
13748 return DateFromFields(isolate,
calendar, merged_fields, options);
13757 Factory* factory = isolate->factory();
13761 return PlainMonthDayOrYearMonthToPlainDate<JSTemporalPlainMonthDay>(
13762 isolate, month_day, item_obj, factory->day_string(),
13763 factory->monthCode_string(), factory->year_string());
13769 Factory* factory = isolate->factory();
13775 factory->
NewJSObject(isolate->object_function());
13779 isolate, fields, factory->calendar_string(),
13800 return TemporalMonthDayToString(isolate, month_day, ShowCalendar::kAuto);
13807 return TemporalToString<JSTemporalPlainMonthDay, TemporalMonthDayToString>(
13808 isolate, month_day, options,
"Temporal.PlainMonthDay.prototype.toString");
13815#ifdef V8_INTL_SUPPORT
13817 isolate, month_day, locales, options,
13818 "Temporal.PlainMonthDay.prototype.toLocaleString");
13820 return TemporalMonthDayToString(isolate, month_day, ShowCalendar::kAuto);
13830 const char* method_name =
"Temporal.PlainYearMonth";
13834 NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
13835 isolate->factory()->NewStringFromAsciiChecked(
13849 ToTemporalCalendarWithISODefault(isolate, calendar_like, method_name));
13856 if (!IsUndefined(*reference_iso_day_obj)) {
13858 ref = reference_iso_day;
13862 return CreateTemporalYearMonth(isolate, target,
new_target, iso_year,
13876 std::optional<ParsedISO8601Result> parsed =
13877 TemporalParser::ParseTemporalYearMonthString(isolate, iso_string);
13878 if (!parsed.has_value()) {
13885 if (parsed->utc_designator) {
13893 DateTimeRecordWithCalendar
result;
13895 isolate,
result, ParseISODateTime(isolate, iso_string, *parsed),
13901 DateRecordWithCalendar ret = {
13907MaybeDirectHandle<JSTemporalPlainYearMonth> ToTemporalYearMonth(
13908 Isolate* isolate, DirectHandle<Object> item_obj,
13909 DirectHandle<Object> options,
const char* method_name) {
13913 DCHECK(IsJSReceiver(*options) || IsUndefined(*options));
13915 if (IsJSReceiver(*item_obj)) {
13919 if (IsJSTemporalPlainYearMonth(*item_obj)) {
13924 DirectHandle<JSReceiver>
calendar;
13927 GetTemporalCalendarWithISODefault(isolate, item, method_name));
13930 DirectHandle<FixedArray> field_names =
13931 MonthMonthCodeYearInFixedArray(isolate);
13933 CalendarFields(isolate,
calendar, field_names));
13935 DirectHandle<JSReceiver> fields;
13937 PrepareTemporalFields(isolate, item, field_names,
13938 RequiredFields::kNone));
13940 return YearMonthFromFields(isolate,
calendar, fields, options);
13944 isolate, ToTemporalOverflow(isolate, options, method_name),
13945 DirectHandle<JSTemporalPlainYearMonth>());
13947 DirectHandle<String>
string;
13951 DateRecordWithCalendar
result;
13953 isolate,
result, ParseTemporalYearMonthString(isolate,
string),
13954 DirectHandle<JSTemporalPlainYearMonth>());
13956 DirectHandle<JSReceiver>
calendar;
13959 ToTemporalCalendarWithISODefault(isolate,
result.calendar, method_name));
13962 DirectHandle<JSTemporalPlainYearMonth> created_result;
13964 isolate, created_result,
13965 CreateTemporalYearMonth(isolate,
result.date.year,
result.date.month,
13971 return YearMonthFromFields(isolate,
calendar, created_result);
13974MaybeDirectHandle<JSTemporalPlainYearMonth> ToTemporalYearMonth(
13975 Isolate* isolate, DirectHandle<Object> item_obj,
const char* method_name) {
13977 return ToTemporalYearMonth(
13978 isolate, item_obj, isolate->factory()->undefined_value(), method_name);
13987 const char* method_name =
"Temporal.PlainYearMonth.from";
13994 if (IsJSTemporalPlainYearMonth(*item)) {
13997 isolate, ToTemporalOverflow(isolate, options, method_name),
14002 return CreateTemporalYearMonth(
14003 isolate, year_month->iso_year(), year_month->iso_month(),
14004 direct_handle(year_month->calendar(), isolate), year_month->iso_day());
14007 return ToTemporalYearMonth(isolate, item, options, method_name);
14014 const char* method_name =
"Temporal.PlainYearMonth.compare";
14018 isolate,
one, ToTemporalYearMonth(isolate, one_obj, method_name));
14022 isolate, two, ToTemporalYearMonth(isolate, two_obj, method_name));
14027 CompareISODate({
one->iso_year(),
one->iso_month(),
one->iso_day()},
14028 {two->iso_year(), two->iso_month(), two->iso_day()})),
14043 ToTemporalYearMonth(isolate, other_obj,
14044 "Temporal.PlainYearMonth.prototype.equals"));
14046 if (year_month->iso_year() != other->iso_year())
14047 return isolate->factory()->false_value();
14049 if (year_month->iso_month() != other->iso_month())
14050 return isolate->factory()->false_value();
14052 if (year_month->iso_day() != other->iso_day())
14053 return isolate->factory()->false_value();
14055 return CalendarEquals(
14063AddDurationToOrSubtractDurationFromPlainYearMonth(
14064 Isolate* isolate, Arithmetic operation,
14077 if (operation == Arithmetic::kSubtract) {
14079 duration = CreateNegatedDurationRecord(isolate, duration).ToChecked();
14085 TimeDurationRecord balance_result;
14087 isolate, balance_result,
14088 BalanceDuration(isolate, Unit::kDay, duration.
time_duration, method_name),
14089 DirectHandle<JSTemporalPlainYearMonth>());
14091 DirectHandle<JSReceiver>
options;
14095 DirectHandle<JSReceiver>
calendar(year_month->calendar(), isolate);
14098 Factory* factory = isolate->factory();
14099 DirectHandle<FixedArray> field_names = MonthCodeYearInFixedArray(isolate);
14101 CalendarFields(isolate,
calendar, field_names));
14104 DirectHandle<JSReceiver> fields;
14107 PrepareTemporalFields(isolate, year_month, field_names,
14108 RequiredFields::kNone));
14116 {balance_result.days, 0, 0, 0, 0, 0, 0}});
14119 DirectHandle<Object> day;
14122 DirectHandle<Object> day_from_calendar;
14124 isolate, day_from_calendar,
14125 temporal::CalendarDaysInMonth(isolate,
calendar, year_month));
14129 ToPositiveInteger(isolate, day_from_calendar));
14141 DirectHandle<JSTemporalPlainDate>
date;
14144 FromFields<JSTemporalPlainDate>(
14145 isolate,
calendar, fields, isolate->factory()->undefined_value(),
14146 isolate->factory()->dateFromFields_string(),
14147 JS_TEMPORAL_PLAIN_DATE_TYPE));
14152 DirectHandle<JSTemporalDuration> duration_to_add =
14153 CreateTemporalDuration(isolate, {duration.
years,
14156 {balance_result.days, 0, 0, 0, 0, 0, 0}})
14157 .ToHandleChecked();
14159 DirectHandle<JSReceiver> options_copy =
14160 isolate->factory()->NewJSObjectWithNullProto();
14170 isolate, options_copy, options,
14172 DirectHandle<JSTemporalPlainYearMonth>());
14176 DirectHandle<JSTemporalPlainDate> added_date;
14178 isolate, added_date,
14179 CalendarDateAdd(isolate,
calendar,
date, duration_to_add, options));
14182 DirectHandle<JSReceiver> added_date_fields;
14184 isolate, added_date_fields,
14185 PrepareTemporalFields(isolate, added_date, field_names,
14186 RequiredFields::kNone));
14189 return FromFields<JSTemporalPlainYearMonth>(
14190 isolate,
calendar, added_date_fields, options_copy,
14191 isolate->factory()->yearMonthFromFields_string(),
14192 JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE);
14201 return AddDurationToOrSubtractDurationFromPlainYearMonth(
14202 isolate, Arithmetic::kAdd, year_month, temporal_duration_like, options,
14203 "Temporal.PlainYearMonth.prototype.add");
14210 return AddDurationToOrSubtractDurationFromPlainYearMonth(
14211 isolate, Arithmetic::kSubtract, year_month, temporal_duration_like,
14212 options,
"Temporal.PlainYearMonth.prototype.subtract");
14218 Isolate* isolate, TimePreposition operation,
14221 const char* method_name) {
14224 double sign = operation == TimePreposition::kSince ? -1 : 1;
14228 isolate, other, ToTemporalYearMonth(isolate, other_obj, method_name));
14234 bool calendar_equals;
14236 isolate, calendar_equals,
14237 CalendarEqualsBool(isolate,
calendar,
14240 if (!calendar_equals) {
14246 DifferenceSettings settings;
14249 GetDifferenceSettings(isolate, operation, options, UnitGroup::kDate,
14250 DisallowedUnitsInDifferenceSettings::kWeekAndDay,
14251 Unit::kMonth, Unit::kYear, method_name),
14252 DirectHandle<JSTemporalDuration>());
14254 Factory* factory = isolate->factory();
14255 DirectHandle<FixedArray> field_names = MonthCodeYearInFixedArray(isolate);
14257 CalendarFields(isolate,
calendar, field_names));
14260 DirectHandle<JSReceiver> other_fields;
14262 PrepareTemporalFields(isolate, other, field_names,
14263 RequiredFields::kNone));
14267 factory->day_string(),
one,
14272 DirectHandle<JSTemporalPlainDate> other_date;
14274 isolate, other_date,
14275 DateFromFields(isolate,
calendar, other_fields,
14276 isolate->factory()->undefined_value()));
14278 DirectHandle<JSReceiver> this_fields;
14280 isolate, this_fields,
14281 PrepareTemporalFields(isolate, year_month, field_names,
14282 RequiredFields::kNone));
14285 factory->day_string(),
one,
14289 DirectHandle<JSTemporalPlainDate> this_date;
14291 isolate, this_date,
14292 DateFromFields(isolate,
calendar, this_fields,
14293 isolate->factory()->undefined_value()));
14296 DirectHandle<JSReceiver> until_options;
14298 isolate, until_options,
14299 MergeLargestUnitOption(isolate, settings.options, settings.largest_unit));
14302 DirectHandle<JSTemporalDuration>
result;
14304 CalendarDateUntil(isolate,
calendar, this_date,
14305 other_date, until_options));
14309 if (settings.smallest_unit != Unit::kMonth ||
14310 settings.rounding_increment != 1) {
14315 DurationRecordWithRemainder round_result;
14317 isolate, round_result,
14318 RoundDuration(isolate,
14322 {0, 0, 0, 0, 0, 0, 0}},
14323 settings.rounding_increment, settings.smallest_unit,
14324 settings.rounding_mode, this_date, method_name),
14325 DirectHandle<JSTemporalDuration>());
14328 return CreateTemporalDuration(isolate, {round_result.record.years *
sign,
14329 round_result.record.months *
sign,
14331 {0, 0, 0, 0, 0, 0, 0}})
14332 .ToHandleChecked();
14336 return CreateTemporalDuration(isolate,
14340 {0, 0, 0, 0, 0, 0, 0}})
14341 .ToHandleChecked();
14351 return DifferenceTemporalPlainYearMonth(
14352 isolate, TimePreposition::kUntil,
handle, other, options,
14353 "Temporal.PlainYearMonth.prototype.until");
14361 return DifferenceTemporalPlainYearMonth(
14362 isolate, TimePreposition::kSince,
handle, other, options,
14363 "Temporal.PlainYearMonth.prototype.since");
14375 MonthMonthCodeYearInFixedArray(isolate);
14377 YearMonthFromFields>(
14378 isolate, temporal_year_month, temporal_year_month_like_obj, options_obj,
14379 field_names,
"Temporal.PlainYearMonth.prototype.with");
14386 Factory* factory = isolate->factory();
14390 return PlainMonthDayOrYearMonthToPlainDate<JSTemporalPlainYearMonth>(
14391 isolate, year_month, item_obj, factory->monthCode_string(),
14392 factory->year_string(), factory->day_string());
14398 Factory* factory = isolate->factory();
14404 isolate->factory()->NewJSObject(isolate->object_function());
14408 isolate, fields, factory->calendar_string(),
14428 return TemporalYearMonthToString(isolate, year_month, ShowCalendar::kAuto);
14435 return TemporalToString<JSTemporalPlainYearMonth, TemporalYearMonthToString>(
14436 isolate, year_month, options,
14437 "Temporal.PlainYearMonth.prototype.toString");
14444#ifdef V8_INTL_SUPPORT
14446 isolate, year_month, locales, options,
14447 "Temporal.PlainYearMonth.prototype.toLocaleString");
14449 return TemporalYearMonthToString(isolate, year_month, ShowCalendar::kAuto);
14460 const char* method_name =
"Temporal.PlainTime";
14466 NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
14467 isolate->factory()->NewStringFromAsciiChecked(
14480 return CreateTemporalTime(
14489 const char* method_name =
"Temporal.PlainTime.prototype.toZonedDateTime";
14490 Factory* factory = isolate->factory();
14495 if (!IsJSReceiver(*item_obj)) {
14503 isolate, temporal_date_like,
14506 if (IsUndefined(*temporal_date_like)) {
14513 isolate, temporal_date,
14514 ToTemporalDate(isolate, temporal_date_like, method_name));
14518 isolate, temporal_time_zone_like,
14521 if (IsUndefined(*temporal_time_zone_like)) {
14540 isolate, temporal_date_time,
14543 {{temporal_date->iso_year(), temporal_date->iso_month(),
14544 temporal_date->iso_day()},
14545 {temporal_time->iso_hour(), temporal_time->iso_minute(),
14546 temporal_time->iso_second(), temporal_time->iso_millisecond(),
14547 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()}},
14554 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, temporal_date_time,
14555 Disambiguation::kCompatible, method_name));
14558 return CreateTemporalZonedDateTime(
14565int32_t CompareTemporalTime(
const TimeRecord& time1,
const TimeRecord& time2) {
14571 if (time1.hour > time2.hour)
return 1;
14573 if (time1.hour < time2.hour)
return -1;
14575 if (time1.minute > time2.minute)
return 1;
14577 if (time1.minute < time2.minute)
return -1;
14579 if (time1.second > time2.second)
return 1;
14581 if (time1.second < time2.second)
return -1;
14583 if (time1.millisecond > time2.millisecond)
return 1;
14585 if (time1.millisecond < time2.millisecond)
return -1;
14587 if (time1.microsecond > time2.microsecond)
return 1;
14589 if (time1.microsecond < time2.microsecond)
return -1;
14591 if (time1.nanosecond > time2.nanosecond)
return 1;
14593 if (time1.nanosecond < time2.nanosecond)
return -1;
14603 const char* method_name =
"Temporal.PainTime.compare";
14618 {
one->iso_hour(),
one->iso_minute(),
14619 one->iso_second(),
one->iso_millisecond(),
14620 one->iso_microsecond(),
one->iso_nanosecond()},
14621 {two->iso_hour(), two->iso_minute(),
14622 two->iso_second(), two->iso_millisecond(),
14623 two->iso_microsecond(), two->iso_nanosecond()})),
14639 "Temporal.PlainTime.prototype.equals"));
14641 if (temporal_time->iso_hour() != other->iso_hour())
14642 return isolate->factory()->false_value();
14644 if (temporal_time->iso_minute() != other->iso_minute())
14645 return isolate->factory()->false_value();
14647 if (temporal_time->iso_second() != other->iso_second())
14648 return isolate->factory()->false_value();
14651 if (temporal_time->iso_millisecond() != other->iso_millisecond())
14652 return isolate->factory()->false_value();
14655 if (temporal_time->iso_microsecond() != other->iso_microsecond())
14656 return isolate->factory()->false_value();
14659 if (temporal_time->iso_nanosecond() != other->iso_nanosecond())
14660 return isolate->factory()->false_value();
14662 return isolate->factory()->true_value();
14668Maximum MaximumTemporalDurationRoundingIncrement(Unit
unit) {
14682 case Unit::kMinute:
14683 case Unit::kSecond:
14687 case Unit::kMillisecond:
14688 case Unit::kMicrosecond:
14689 case Unit::kNanosecond:
14691 return {
true, 1000};
14703 const char* method_name =
"Temporal.PlainTime.prototype.round";
14704 Factory* factory = isolate->factory();
14709 if (IsUndefined(*round_to_obj)) {
14716 if (IsString(*round_to_obj)) {
14724 factory->smallestUnit_string(),
14739 GetTemporalUnit(isolate, round_to,
"smallestUnit", UnitGroup::kTime,
14740 Unit::kNotPresent,
true, method_name),
14747 ToTemporalRoundingMode(isolate, round_to, RoundingMode::kHalfExpand,
14752 Maximum maximum = MaximumTemporalDurationRoundingIncrement(
smallest_unit);
14759 ToTemporalRoundingIncrement(isolate, round_to, maximum.value,
14760 maximum.defined,
false),
14768 DateTimeRecord
result = RoundTime(
14770 {temporal_time->iso_hour(), temporal_time->iso_minute(),
14771 temporal_time->iso_second(), temporal_time->iso_millisecond(),
14772 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()},
14777 return CreateTemporalTime(isolate,
result.time);
14785 const char* method_name =
"Temporal.PlainTime.prototype.with";
14790 if (!IsJSReceiver(*temporal_time_like_obj)) {
14797 MAYBE_RETURN(RejectObjectWithCalendarOrTimeZone(isolate, temporal_time_like),
14804 isolate, temporal_time_like,
14805 {temporal_time->iso_hour(), temporal_time->iso_minute(),
14806 temporal_time->iso_second(), temporal_time->iso_millisecond(),
14807 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()},
14818 isolate, overflow, ToTemporalOverflow(isolate, options, method_name),
14829 return CreateTemporalTime(isolate,
result);
14835 const char* method_name =
"Temporal.Now.plainTimeISO";
14841 isolate, date_time,
14842 SystemDateTime(isolate, temporal_time_zone_like,
calendar, method_name));
14847 return CreateTemporalTime(
14849 {date_time->iso_hour(), date_time->iso_minute(),
14850 date_time->iso_second(), date_time->iso_millisecond(),
14851 date_time->iso_microsecond(), date_time->iso_nanosecond()})
14852 .ToHandleChecked();
14859 const char* method_name =
"Temporal.PlainTime.from";
14867 isolate, overflow, ToTemporalOverflow(isolate, options, method_name),
14871 if (IsJSTemporalPlainTime(*item_obj)) {
14876 return CreateTemporalTime(
14877 isolate, {item->iso_hour(), item->iso_minute(), item->iso_second(),
14878 item->iso_millisecond(), item->iso_microsecond(),
14879 item->iso_nanosecond()});
14895 isolate, temporal_date,
14896 ToTemporalDate(isolate, temporal_date_like,
14897 "Temporal.PlainTime.prototype.toPlainDateTime"));
14906 {{temporal_date->iso_year(), temporal_date->iso_month(),
14907 temporal_date->iso_day()},
14908 {temporal_time->iso_hour(), temporal_time->iso_minute(),
14909 temporal_time->iso_second(), temporal_time->iso_millisecond(),
14910 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()}},
14918AddDurationToOrSubtractDurationFromPlainTime(
14919 Isolate* isolate, Arithmetic operation,
14923 double sign = operation == Arithmetic::kSubtract ? -1.0 : 1.0;
14931 TimeDurationRecord& time_duration = duration.
time_duration;
14940 DateTimeRecord
result = AddTime(
14942 {temporal_time->iso_hour(), temporal_time->iso_minute(),
14943 temporal_time->iso_second(), temporal_time->iso_millisecond(),
14944 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()},
14945 {0,
sign * time_duration.hours,
sign * time_duration.minutes,
14946 sign * time_duration.seconds,
sign * time_duration.milliseconds,
14947 sign * time_duration.microseconds,
sign * time_duration.nanoseconds});
14955 return CreateTemporalTime(isolate,
result.time);
14964 return AddDurationToOrSubtractDurationFromPlainTime(
14965 isolate, Arithmetic::kAdd, temporal_time, temporal_duration_like,
14966 "Temporal.PlainTime.prototype.add");
14973 return AddDurationToOrSubtractDurationFromPlainTime(
14974 isolate, Arithmetic::kSubtract, temporal_time, temporal_duration_like,
14975 "Temporal.PlainTime.prototype.subtract");
14981 Isolate* isolate, TimePreposition operation,
14984 const char* method_name) {
14987 double sign = operation == TimePreposition::kSince ? -1 : 1;
14996 DifferenceSettings settings;
14999 GetDifferenceSettings(isolate, operation, options, UnitGroup::kTime,
15000 DisallowedUnitsInDifferenceSettings::kNone,
15001 Unit::kNanosecond, Unit::kHour, method_name),
15009 DurationRecordWithRemainder
result;
15010 result.record.time_duration =
15013 {temporal_time->iso_hour(), temporal_time->iso_minute(),
15014 temporal_time->iso_second(), temporal_time->iso_millisecond(),
15015 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()},
15016 {other->iso_hour(), other->iso_minute(), other->iso_second(),
15017 other->iso_millisecond(), other->iso_microsecond(),
15018 other->iso_nanosecond()})
15026 result.record.time_duration.days = 0;
15028 RoundDuration(isolate,
result.record, settings.rounding_increment,
15029 settings.smallest_unit, settings.rounding_mode, method_name)
15034 result.record.time_duration.days = 0;
15035 result.record.time_duration =
15036 BalanceDuration(isolate, settings.largest_unit,
15037 result.record.time_duration, method_name)
15045 result.record.time_duration.days = 0;
15047 result.record.time_duration.minutes *=
sign;
15048 result.record.time_duration.seconds *=
sign;
15049 result.record.time_duration.milliseconds *=
sign;
15050 result.record.time_duration.microseconds *=
sign;
15051 result.record.time_duration.nanoseconds *=
sign;
15052 return CreateTemporalDuration(isolate,
result.record).ToHandleChecked();
15062 return DifferenceTemporalPlainTime(isolate, TimePreposition::kUntil,
handle,
15064 "Temporal.PlainTime.prototype.until");
15072 return DifferenceTemporalPlainTime(isolate, TimePreposition::kSince,
handle,
15074 "Temporal.PlainTime.prototype.since");
15080 Factory* factory = isolate->factory();
15086 isolate->factory()->NewJSObject(isolate->object_function());
15092 factory->calendar_string(),
15121 return TemporalTimeToString(isolate, temporal_time, Precision::kAuto);
15128#ifdef V8_INTL_SUPPORT
15130 isolate, temporal_time, locales, options,
15131 "Temporal.PlainTime.prototype.toLocaleString");
15133 return TemporalTimeToString(isolate, temporal_time, Precision::kAuto);
15141 bool is_negative) {
15147 case RoundingMode::kCeil:
15148 return UnsignedRoundingMode::kZero;
15149 case RoundingMode::kFloor:
15150 return UnsignedRoundingMode::kInfinity;
15151 case RoundingMode::kExpand:
15152 return UnsignedRoundingMode::kInfinity;
15153 case RoundingMode::kTrunc:
15154 return UnsignedRoundingMode::kZero;
15155 case RoundingMode::kHalfCeil:
15156 return UnsignedRoundingMode::kHalfZero;
15157 case RoundingMode::kHalfFloor:
15158 return UnsignedRoundingMode::kHalfInfinity;
15159 case RoundingMode::kHalfExpand:
15160 return UnsignedRoundingMode::kHalfInfinity;
15161 case RoundingMode::kHalfTrunc:
15162 return UnsignedRoundingMode::kHalfZero;
15163 case RoundingMode::kHalfEven:
15164 return UnsignedRoundingMode::kHalfEven;
15170 case RoundingMode::kCeil:
15171 return UnsignedRoundingMode::kInfinity;
15172 case RoundingMode::kFloor:
15173 return UnsignedRoundingMode::kZero;
15174 case RoundingMode::kExpand:
15175 return UnsignedRoundingMode::kInfinity;
15176 case RoundingMode::kTrunc:
15177 return UnsignedRoundingMode::kZero;
15178 case RoundingMode::kHalfCeil:
15179 return UnsignedRoundingMode::kHalfInfinity;
15180 case RoundingMode::kHalfFloor:
15181 return UnsignedRoundingMode::kHalfZero;
15182 case RoundingMode::kHalfExpand:
15183 return UnsignedRoundingMode::kHalfInfinity;
15184 case RoundingMode::kHalfTrunc:
15185 return UnsignedRoundingMode::kHalfZero;
15186 case RoundingMode::kHalfEven:
15187 return UnsignedRoundingMode::kHalfEven;
15192double ApplyUnsignedRoundingMode(
double x,
double r1,
double r2,
15193 UnsignedRoundingMode unsigned_rounding_mode) {
15195 if (
x == r1)
return r1;
15201 if (unsigned_rounding_mode == UnsignedRoundingMode::kZero)
return r1;
15203 if (unsigned_rounding_mode == UnsignedRoundingMode::kInfinity)
return r2;
15205 double d1 =
x - r1;
15207 double d2 = r2 -
x;
15209 if (d1 < d2)
return r1;
15211 if (d2 < d1)
return r2;
15215 if (unsigned_rounding_mode == UnsignedRoundingMode::kHalfZero)
return r1;
15217 if (unsigned_rounding_mode == UnsignedRoundingMode::kHalfInfinity)
return r2;
15219 DCHECK_EQ(unsigned_rounding_mode, UnsignedRoundingMode::kHalfEven);
15221 int64_t cardinality =
static_cast<int64_t
>(r1) % 2;
15223 if (cardinality == 0)
return r1;
15229DirectHandle<BigInt> ApplyUnsignedRoundingMode(
15230 Isolate* isolate, DirectHandle<BigInt> num, DirectHandle<BigInt>
increment,
15231 DirectHandle<BigInt> r1, DirectHandle<BigInt> r2,
15232 UnsignedRoundingMode unsigned_rounding_mode) {
15234 DirectHandle<BigInt> rr1 =
15236 DirectHandle<BigInt> rr2 =
15244 if (unsigned_rounding_mode == UnsignedRoundingMode::kZero)
return r1;
15246 if (unsigned_rounding_mode == UnsignedRoundingMode::kInfinity)
return r2;
15248 DirectHandle<BigInt> dd1 =
15251 DirectHandle<BigInt> dd2 =
15264 if (unsigned_rounding_mode == UnsignedRoundingMode::kHalfZero)
return r1;
15266 if (unsigned_rounding_mode == UnsignedRoundingMode::kHalfInfinity)
return r2;
15268 DCHECK_EQ(unsigned_rounding_mode, UnsignedRoundingMode::kHalfEven);
15270 DirectHandle<BigInt> cardinality =
15272 .ToHandleChecked();
15274 if (!cardinality->ToBoolean())
return r1;
15281double RoundNumberToIncrement(Isolate* isolate,
double x,
double increment,
15289 if (quotient < 0) {
15291 is_negative =
true;
15293 quotient = -quotient;
15297 is_negative =
false;
15301 UnsignedRoundingMode unsigned_rounding_mode =
15305 double r1 = std::floor(quotient);
15307 double r2 = std::floor(quotient + 1);
15311 ApplyUnsignedRoundingMode(quotient, r1, r2, unsigned_rounding_mode);
15314 rounded = -rounded;
15321DirectHandle<BigInt> RoundNumberToIncrementAsIfPositive(
15322 Isolate* isolate, DirectHandle<BigInt>
x,
double increment,
15329 UnsignedRoundingMode unsigned_rounding_mode =
15332 DirectHandle<BigInt> increment_bigint =
15334 .ToHandleChecked();
15336 DirectHandle<BigInt> r1 =
15350 DirectHandle<BigInt> rounded = ApplyUnsignedRoundingMode(
15351 isolate,
x, increment_bigint, r1, r2, unsigned_rounding_mode);
15353 DirectHandle<BigInt>
result =
15358DateTimeRecord RoundTime(Isolate* isolate,
const TimeRecord& time,
15367 double fractional_second =
15368 static_cast<double>(time.nanosecond) / 100000000.0 +
15369 static_cast<double>(time.microsecond) / 1000000.0 +
15370 static_cast<double>(time.millisecond) / 1000.0 +
15371 static_cast<double>(time.second);
15380 (((((time.hour * 60.0 + time.minute) * 60.0 + time.second) * 1000.0 +
15381 time.millisecond) *
15383 time.microsecond) *
15391 quantity = (fractional_second / 60.0 + time.minute) / 60.0 + time.hour;
15394 case Unit::kMinute:
15396 quantity = fractional_second / 60.0 + time.minute;
15399 case Unit::kSecond:
15401 quantity = fractional_second;
15404 case Unit::kMillisecond:
15407 quantity = time.nanosecond / 1000000.0 + time.microsecond / 1000.0 +
15411 case Unit::kMicrosecond:
15413 quantity = time.nanosecond / 1000.0 + time.microsecond;
15420 quantity = time.nanosecond;
15434 return {{0, 0,
result}, {0, 0, 0, 0, 0, 0}};
15438 return BalanceTime({
static_cast<double>(
result), 0, 0, 0, 0, 0});
15440 case Unit::kMinute:
15442 return BalanceTime({
static_cast<double>(time.hour),
15443 static_cast<double>(
result), 0, 0, 0, 0});
15445 case Unit::kSecond:
15447 return BalanceTime({
static_cast<double>(time.hour),
15448 static_cast<double>(time.minute),
15449 static_cast<double>(
result), 0, 0, 0});
15451 case Unit::kMillisecond:
15453 return BalanceTime({
static_cast<double>(time.hour),
15454 static_cast<double>(time.minute),
15455 static_cast<double>(time.second),
15456 static_cast<double>(
result), 0, 0});
15458 case Unit::kMicrosecond:
15460 return BalanceTime({
static_cast<double>(time.hour),
15461 static_cast<double>(time.minute),
15462 static_cast<double>(time.second),
15463 static_cast<double>(time.millisecond),
15464 static_cast<double>(
result), 0});
15470 return BalanceTime(
15471 {
static_cast<double>(time.hour),
static_cast<double>(time.minute),
15472 static_cast<double>(time.second),
15473 static_cast<double>(time.millisecond),
15474 static_cast<double>(time.microsecond),
static_cast<double>(
result)});
15479Maybe<StringPrecision> ToSecondsStringPrecision(
15480 Isolate* isolate, DirectHandle<JSReceiver> normalized_options,
15481 const char* method_name) {
15487 GetTemporalUnit(isolate, normalized_options,
"smallestUnit",
15488 UnitGroup::kTime, Unit::kNotPresent,
false, method_name),
15496 NewRangeError(MessageTemplate::kPropertyValueOutOfRange,
15497 isolate->factory()->smallestUnit_string()),
15500 case Unit::kMinute:
15503 return Just(StringPrecision({Precision::kMinute, Unit::kMinute, 1}));
15505 case Unit::kSecond:
15508 return Just(StringPrecision({Precision::k0, Unit::kSecond, 1}));
15510 case Unit::kMillisecond:
15513 return Just(StringPrecision({Precision::k3, Unit::kMillisecond, 1}));
15515 case Unit::kMicrosecond:
15518 return Just(StringPrecision({Precision::k6, Unit::kMicrosecond, 1}));
15520 case Unit::kNanosecond:
15523 return Just(StringPrecision({Precision::k9, Unit::kNanosecond, 1}));
15527 Factory* factory = isolate->factory();
15532 DirectHandle<Object> fractional_digits_val;
15534 isolate, fractional_digits_val,
15536 factory->fractionalSecondDigits_string()),
15540 if (!
IsNumber(*fractional_digits_val)) {
15542 if (!IsUndefined(*fractional_digits_val)) {
15545 DirectHandle<String>
string;
15552 NewRangeError(MessageTemplate::kPropertyValueOutOfRange,
15553 factory->fractionalSecondDigits_string()),
15559 return Just(StringPrecision({Precision::kAuto, Unit::kNanosecond, 1}));
15563 if (
IsNaN(*fractional_digits_val) ||
15567 NewRangeError(MessageTemplate::kPropertyValueOutOfRange,
15568 factory->fractionalSecondDigits_string()),
15572 int64_t fractional_digit_count = RoundTowardsZero(
15576 if (fractional_digit_count < 0 || fractional_digit_count > 9) {
15579 NewRangeError(MessageTemplate::kPropertyValueOutOfRange,
15580 factory->fractionalSecondDigits_string()),
15584 switch (fractional_digit_count) {
15588 return Just(StringPrecision({Precision::k0, Unit::kSecond, 1}));
15593 return Just(StringPrecision({Precision::k1, Unit::kMillisecond, 100}));
15595 return Just(StringPrecision({Precision::k2, Unit::kMillisecond, 10}));
15597 return Just(StringPrecision({Precision::k3, Unit::kMillisecond, 1}));
15602 return Just(StringPrecision({Precision::k4, Unit::kMicrosecond, 100}));
15604 return Just(StringPrecision({Precision::k5, Unit::kMicrosecond, 10}));
15606 return Just(StringPrecision({Precision::k6, Unit::kMicrosecond, 1}));
15611 return Just(StringPrecision({Precision::k7, Unit::kNanosecond, 100}));
15613 return Just(StringPrecision({Precision::k8, Unit::kNanosecond, 10}));
15615 return Just(StringPrecision({Precision::k9, Unit::kNanosecond, 1}));
15622MaybeDirectHandle<Smi> CompareEpochNanoseconds(Isolate* isolate,
15623 DirectHandle<BigInt>
one,
15624 DirectHandle<BigInt> two) {
15641 const char* method_name =
"Temporal.PlainTime.prototype.toString";
15654 ToSecondsStringPrecision(isolate, options, method_name),
15661 ToTemporalRoundingMode(isolate, options, RoundingMode::kTrunc,
15671 DateTimeRecord round_result = RoundTime(
15673 {temporal_time->iso_hour(), temporal_time->iso_minute(),
15674 temporal_time->iso_second(), temporal_time->iso_millisecond(),
15675 temporal_time->iso_microsecond(), temporal_time->iso_nanosecond()},
15681 return TemporalTimeToString(isolate, round_result.time,
precision.precision);
15690 const char* method_name =
"Temporal.ZonedDateTime";
15695 NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
15696 isolate->factory()->NewStringFromAsciiChecked(
15702 isolate, epoch_nanoseconds,
15703 BigInt::FromObject(isolate, epoch_nanoseconds_obj));
15706 if (!IsValidEpochNanoseconds(isolate, epoch_nanoseconds)) {
15720 ToTemporalCalendarWithISODefault(isolate, calendar_like, method_name));
15724 return CreateTemporalZonedDateTime(isolate, target,
new_target,
15732 const char* method_name =
"Temporal.ZonedDateTime.prototype.hoursInDay";
15742 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
15743 .ToHandleChecked();
15752 isolate, temporal_date_time,
15754 iso_calendar, method_name));
15765 {{temporal_date_time->iso_year(), temporal_date_time->iso_month(),
15766 temporal_date_time->iso_day()},
15767 {0, 0, 0, 0, 0, 0}},
15770 DateRecord tomorrow_fields = BalanceISODate(
15771 isolate, {temporal_date_time->iso_year(), temporal_date_time->iso_month(),
15772 temporal_date_time->iso_day() + 1});
15781 isolate, {tomorrow_fields, {0, 0, 0, 0, 0, 0}}, iso_calendar));
15786 isolate, today_instant,
15787 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, today,
15788 Disambiguation::kCompatible, method_name));
15793 isolate, tomorrow_instant,
15794 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, tomorrow,
15795 Disambiguation::kCompatible, method_name));
15802 .ToHandleChecked();
15809 int64_t diff_seconds =
15813 double hours_in_that_day =
static_cast<double>(diff_seconds) / 3600.0;
15814 return isolate->factory()->NewNumber(hours_in_that_day);
15825 Factory* factory = isolate->factory();
15827 DCHECK(IsUndefined(*options) || IsJSReceiver(*options));
15829 OffsetBehaviour offset_behaviour = OffsetBehaviour::kOption;
15831 MatchBehaviour match_behaviour = MatchBehaviour::kMatchExactly;
15840 if (IsJSReceiver(*item_obj)) {
15844 if (IsJSTemporalZonedDateTime(*item_obj)) {
15851 GetTemporalCalendarWithISODefault(isolate, item, method_name));
15855 DirectHandle<FixedArray> field_names = All10UnitsInFixedArray(isolate);
15857 CalendarFields(isolate,
calendar, field_names));
15860 int32_t field_length = field_names->length();
15862 factory->timeZone_string());
15866 factory->offset_string());
15867 field_names->RightTrim(isolate, field_length);
15871 DirectHandle<JSReceiver> fields;
15874 PrepareTemporalFields(isolate, item, field_names,
15875 RequiredFields::kTimeZone));
15878 DirectHandle<Object> time_zone_obj;
15880 isolate, time_zone_obj,
15895 offset_behaviour = OffsetBehaviour::kWall;
15907 InterpretTemporalDateTimeFields(isolate,
calendar, fields, options,
15909 DirectHandle<JSTemporalZonedDateTime>());
15914 isolate, ToTemporalOverflow(isolate, options, method_name),
15915 DirectHandle<JSTemporalZonedDateTime>());
15917 DirectHandle<String>
string;
15921 DateTimeRecordWithCalendar parsed_result;
15923 isolate, parsed_result,
15924 ParseTemporalZonedDateTimeString(isolate,
string),
15925 DirectHandle<JSTemporalZonedDateTime>());
15926 result = {parsed_result.date, parsed_result.time};
15930 DCHECK(!IsUndefined(*parsed_result.time_zone.name));
15931 DirectHandle<String> time_zone_name =
15936 std::optional<ParsedISO8601Result> parsed =
15937 TemporalParser::ParseTimeZoneNumericUTCOffset(isolate, time_zone_name);
15938 if (!parsed.has_value()) {
15941 if (!IsValidTimeZoneName(isolate, time_zone_name)) {
15944 DirectHandle<JSTemporalZonedDateTime>());
15947 time_zone_name = CanonicalizeTimeZoneName(isolate, time_zone_name);
15953 if (parsed_result.time_zone.z) {
15955 offset_behaviour = OffsetBehaviour::kExact;
15959 offset_behaviour = OffsetBehaviour::kWall;
15963 .ToHandleChecked();
15968 ToTemporalCalendarWithISODefault(isolate, parsed_result.calendar,
15971 match_behaviour = MatchBehaviour::kMatchMinutes;
15974 int64_t offset_nanoseconds = 0;
15977 if (offset_behaviour == OffsetBehaviour::kOption) {
15981 isolate, offset_nanoseconds,
15983 DirectHandle<JSTemporalZonedDateTime>());
15987 Disambiguation disambiguation;
15989 isolate, disambiguation,
15990 ToTemporalDisambiguation(isolate, options, method_name),
15991 DirectHandle<JSTemporalZonedDateTime>());
15997 ToTemporalOffset(isolate, options, Offset::kReject, method_name),
15998 DirectHandle<JSTemporalZonedDateTime>());
16006 DirectHandle<BigInt> epoch_nanoseconds;
16008 isolate, epoch_nanoseconds,
16009 InterpretISODateTimeOffset(isolate,
result, offset_behaviour,
16010 offset_nanoseconds,
time_zone, disambiguation,
16011 offset, match_behaviour, method_name));
16015 return CreateTemporalZonedDateTime(isolate, epoch_nanoseconds,
time_zone,
16019MaybeDirectHandle<JSTemporalZonedDateTime> ToTemporalZonedDateTime(
16020 Isolate* isolate, DirectHandle<Object> item_obj,
const char* method_name) {
16022 return ToTemporalZonedDateTime(
16023 isolate, item_obj, isolate->factory()->undefined_value(), method_name);
16032 const char* method_name =
"Temporal.ZonedDateTime.from";
16040 if (IsJSTemporalZonedDateTime(*item)) {
16043 isolate, ToTemporalOverflow(isolate, options, method_name),
16048 Disambiguation disambiguation;
16050 isolate, disambiguation,
16051 ToTemporalDisambiguation(isolate, options, method_name),
16053 USE(disambiguation);
16061 ToTemporalOffset(isolate, options, Offset::kReject, method_name),
16069 return CreateTemporalZonedDateTime(
16070 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate),
16075 return ToTemporalZonedDateTime(isolate, item, options, method_name);
16083 const char* method_name =
"Temporal.ZonedDateTime.compare";
16087 isolate,
one, ToTemporalZonedDateTime(isolate, one_obj, method_name));
16091 isolate, two, ToTemporalZonedDateTime(isolate, two_obj, method_name));
16094 return CompareEpochNanoseconds(isolate,
16105 if (
one.is_identical_to(two)) {
16110 DirectHandle<String> time_zone_one;
16114 DirectHandle<String> time_zone_two;
16122 return Just(
false);
16132 const char* method_name =
"Temporal.ZonedDateTime.prototype.equals";
16133 Factory* factory = isolate->factory();
16140 isolate, other, ToTemporalZonedDateTime(isolate, other_obj, method_name));
16143 other->nanoseconds())) {
16144 return factory->false_value();
16151 TimeZoneEquals(isolate,
16156 return factory->false_value();
16159 return CalendarEquals(isolate,
16168 Isolate* isolate,
const DateTimeRecord& data,
16169 OffsetBehaviour offset_behaviour, int64_t offset_nanoseconds,
16171 Offset offset_option, MatchBehaviour match_behaviour,
16172 const char* method_name) {
16184 isolate, {data.date, data.time},
calendar));
16187 if (offset_behaviour == OffsetBehaviour::kWall ||
16188 offset_option == Offset::kIgnore) {
16191 DirectHandle<JSTemporalInstant> instant;
16194 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, date_time,
16195 disambiguation, method_name));
16200 if (offset_behaviour == OffsetBehaviour::kExact ||
16201 offset_option == Offset::kUse) {
16204 DirectHandle<BigInt> epoch_nanoseconds =
16205 GetEpochFromISOParts(isolate, {data.date, data.time});
16208 epoch_nanoseconds =
16211 .ToHandleChecked();
16214 if (!IsValidEpochNanoseconds(isolate, epoch_nanoseconds)) {
16218 return epoch_nanoseconds;
16221 DCHECK_EQ(offset_behaviour, OffsetBehaviour::kOption);
16223 DCHECK(offset_option == Offset::kPrefer || offset_option == Offset::kReject);
16225 DirectHandle<FixedArray> possible_instants;
16227 isolate, possible_instants,
16231 for (
int i = 0;
i < possible_instants->
length();
i++) {
16232 DCHECK(IsJSTemporalInstant(possible_instants->get(
i)));
16233 DirectHandle<JSTemporalInstant> candidate(
16237 int64_t candidate_nanoseconds;
16239 isolate, candidate_nanoseconds,
16240 GetOffsetNanosecondsFor(isolate,
time_zone, candidate, method_name),
16241 DirectHandle<BigInt>());
16243 if (candidate_nanoseconds == offset_nanoseconds) {
16245 return DirectHandle<BigInt>(candidate->nanoseconds(), isolate);
16248 if (match_behaviour == MatchBehaviour::kMatchMinutes) {
16251 double rounded_candidate_nanoseconds = RoundNumberToIncrement(
16252 isolate, candidate_nanoseconds, 6e10, RoundingMode::kHalfExpand);
16254 if (rounded_candidate_nanoseconds == offset_nanoseconds) {
16256 return DirectHandle<BigInt>(candidate->nanoseconds(), isolate);
16261 if (offset_option == Offset::kReject) {
16266 DirectHandle<JSTemporalInstant> instant;
16269 DisambiguatePossibleInstants(isolate, possible_instants,
time_zone,
16270 date_time, disambiguation, method_name));
16272 return DirectHandle<BigInt>(instant->nanoseconds(), isolate);
16283 const char* method_name =
"Temporal.ZonedDateTime.prototype.with";
16284 Factory* factory = isolate->factory();
16289 if (!IsJSReceiver(*temporal_zoned_date_time_like_obj)) {
16297 isolate, temporal_zoned_date_time_like),
16308 isolate, field_names,
16309 CalendarFields(isolate,
calendar, All10UnitsInFixedArray(isolate)));
16312 int32_t field_length = field_names->length();
16314 factory->offset_string());
16315 field_names->RightTrim(isolate, field_length);
16321 isolate, partial_zoned_date_time,
16322 PreparePartialTemporalFields(isolate, temporal_zoned_date_time_like,
16330 Disambiguation disambiguation;
16332 isolate, disambiguation,
16333 ToTemporalDisambiguation(isolate, options, method_name),
16340 ToTemporalOffset(isolate, options, Offset::kPrefer, method_name),
16347 field_length = field_names->length();
16349 factory->timeZone_string());
16350 field_names->RightTrim(isolate, field_length);
16357 PrepareTemporalFields(isolate, zoned_date_time, field_names,
16358 RequiredFields::kTimeZoneAndOffset));
16363 CalendarMergeFields(isolate,
calendar, fields, partial_zoned_date_time));
16369 PrepareTemporalFields(isolate, fields, field_names,
16370 RequiredFields::kTimeZoneAndOffset));
16385 isolate, date_time_result,
16386 InterpretTemporalDateTimeFields(isolate,
calendar, fields, options,
16391 int64_t offset_nanoseconds;
16393 isolate, offset_nanoseconds,
16406 isolate, epoch_nanoseconds,
16407 InterpretISODateTimeOffset(
16408 isolate, {date_time_result.
date, date_time_result.
time},
16409 OffsetBehaviour::kOption, offset_nanoseconds,
time_zone,
16410 disambiguation,
offset, MatchBehaviour::kMatchExactly, method_name));
16414 return CreateTemporalZonedDateTime(isolate, epoch_nanoseconds,
time_zone,
16424 const char* method_name =
"Temporal.ZonedDateTime.prototype.withCalendar";
16447 const char* method_name =
"Temporal.ZonedDateTime.prototype.withPlainDate";
16454 isolate, plain_date,
16455 ToTemporalDate(isolate, plain_date_like, method_name));
16462 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
16463 .ToHandleChecked();
16470 isolate, plain_date_time,
16473 direct_handle(zoned_date_time->calendar(), isolate), method_name));
16479 ConsolidateCalendars(isolate,
16491 isolate, result_plain_date_time,
16494 {{plain_date->iso_year(), plain_date->iso_month(),
16495 plain_date->iso_day()},
16496 {plain_date_time->iso_hour(), plain_date_time->iso_minute(),
16497 plain_date_time->iso_second(), plain_date_time->iso_millisecond(),
16498 plain_date_time->iso_microsecond(),
16499 plain_date_time->iso_nanosecond()}},
16505 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, result_plain_date_time,
16506 Disambiguation::kCompatible, method_name));
16509 return CreateTemporalZonedDateTime(
16520 const char* method_name =
"Temporal.ZonedDateTime.prototype.withPlainTime";
16526 if (IsUndefined(*plain_time_like)) {
16529 CreateTemporalTime(isolate, {0, 0, 0, 0, 0, 0}));
16534 isolate, plain_time,
16542 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
16543 .ToHandleChecked();
16550 isolate, plain_date_time,
16561 isolate, result_plain_date_time,
16564 {{plain_date_time->iso_year(), plain_date_time->iso_month(),
16565 plain_date_time->iso_day()},
16566 {plain_time->iso_hour(), plain_time->iso_minute(),
16567 plain_time->iso_second(), plain_time->iso_millisecond(),
16568 plain_time->iso_microsecond(), plain_time->iso_nanosecond()}},
16574 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, result_plain_date_time,
16575 Disambiguation::kCompatible, method_name));
16578 return CreateTemporalZonedDateTime(
16589 const char* method_name =
"Temporal.ZonedDateTime.prototype.withTimeZone";
16608template <typename T, MaybeDirectHandle<T> (*from_fields_func)(
16614 const char* method_name) {
16616 Factory* factory = isolate->factory();
16625 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
16626 .ToHandleChecked();
16633 isolate, temporal_date_time,
16639 field_names->set(0, *field_name_1);
16640 field_names->set(1, *field_name_2);
16642 CalendarFields(isolate,
calendar, field_names));
16647 PrepareTemporalFields(isolate, temporal_date_time, field_names,
16648 RequiredFields::kNone));
16650 return from_fields_func(isolate,
calendar, fields,
16651 factory->undefined_value());
16655MaybeDirectHandle<JSTemporalPlainYearMonth>
16659 YearMonthFromFields>(
16660 isolate, zoned_date_time, isolate->factory()->monthCode_string(),
16661 isolate->factory()->year_string(),
16662 "Temporal.ZonedDateTime.prototype.toPlainYearMonth");
16670 MonthDayFromFields>(
16671 isolate, zoned_date_time, isolate->factory()->day_string(),
16672 isolate->factory()->monthCode_string(),
16673 "Temporal.ZonedDateTime.prototype.toPlainMonthDay");
16681 Precision
precision, ShowCalendar show_calendar,
16682 ShowTimeZone show_time_zone, ShowOffset show_offset,
double increment,
16687 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate),
16705 isolate, temporal_date_time,
16707 iso_calendar, method_name));
16717 isolate, date_time_string,
16718 TemporalDateTimeToString(
16720 {{temporal_date_time->iso_year(), temporal_date_time->iso_month(),
16721 temporal_date_time->iso_day()},
16722 {temporal_date_time->iso_hour(), temporal_date_time->iso_minute(),
16723 temporal_date_time->iso_second(),
16724 temporal_date_time->iso_millisecond(),
16725 temporal_date_time->iso_microsecond(),
16726 temporal_date_time->iso_nanosecond()}},
16727 iso_calendar,
precision, ShowCalendar::kNever));
16729 IncrementalStringBuilder builder(isolate);
16730 builder.AppendString(date_time_string);
16733 if (show_offset == ShowOffset::kNever) {
16740 isolate, offset_ns,
16741 GetOffsetNanosecondsFor(isolate,
time_zone, instant, method_name),
16742 DirectHandle<String>());
16744 builder.AppendString(FormatISOTimeZoneOffsetString(isolate, offset_ns));
16748 if (show_time_zone == ShowTimeZone::kNever) {
16753 DirectHandle<String> time_zone_id;
16759 builder.AppendCStringLiteral(
"[");
16760 builder.AppendString(time_zone_id);
16761 builder.AppendCStringLiteral(
"]");
16765 DirectHandle<String> calendar_string;
16767 isolate, calendar_string,
16768 MaybeFormatCalendarAnnotation(
16769 isolate,
direct_handle(zoned_date_time->calendar(), isolate),
16774 builder.AppendString(calendar_string);
16775 return builder.Finish();
16779MaybeDirectHandle<String> TemporalZonedDateTimeToString(
16780 Isolate* isolate, DirectHandle<JSTemporalZonedDateTime> zoned_date_time,
16781 Precision
precision, ShowCalendar show_calendar,
16782 ShowTimeZone show_time_zone, ShowOffset show_offset,
16783 const char* method_name) {
16789 return TemporalZonedDateTimeToString(
16790 isolate, zoned_date_time,
precision, show_calendar, show_time_zone,
16791 show_offset, 1, Unit::kNanosecond, RoundingMode::kTrunc, method_name);
16804 return TemporalZonedDateTimeToString(
16805 isolate, zoned_date_time, Precision::kAuto, ShowCalendar::kAuto,
16806 ShowTimeZone::kAuto, ShowOffset::kAuto,
16807 "Temporal.ZonedDateTime.prototype.toJSON");
16814 const char* method_name =
"Temporal.ZonedDateTime.prototype.toLocaleString";
16815#ifdef V8_INTL_SUPPORT
16817 isolate, zoned_date_time, locales, options, method_name);
16819 return TemporalZonedDateTimeToString(
16820 isolate, zoned_date_time, Precision::kAuto, ShowCalendar::kAuto,
16821 ShowTimeZone::kAuto, ShowOffset::kAuto, method_name);
16829 const char* method_name =
"Temporal.ZonedDateTime.prototype.toString";
16842 ToSecondsStringPrecision(isolate, options, method_name),
16849 ToTemporalRoundingMode(isolate, options, RoundingMode::kTrunc,
16854 ShowCalendar show_calendar;
16856 isolate, show_calendar,
16857 ToShowCalendarOption(isolate, options, method_name),
16861 ShowTimeZone show_time_zone;
16863 isolate, show_time_zone,
16864 ToShowTimeZoneNameOption(isolate, options, method_name),
16868 ShowOffset show_offset;
16870 isolate, show_offset, ToShowOffsetOption(isolate, options, method_name),
16876 return TemporalZonedDateTimeToString(
16877 isolate, zoned_date_time,
precision.precision, show_calendar,
16886 const char* method_name =
"Temporal.Now.zonedDateTime";
16888 return SystemZonedDateTime(isolate, temporal_time_zone_like, calendar_like,
16896 const char* method_name =
"Temporal.Now.zonedDateTimeISO";
16900 return SystemZonedDateTime(isolate, temporal_time_zone_like,
calendar,
16908 const char* method_name =
"Temporal.ZonedDateTime.prototype.round";
16909 Factory* factory = isolate->factory();
16914 if (IsUndefined(*round_to_obj)) {
16921 if (IsString(*round_to_obj)) {
16929 factory->smallestUnit_string(),
16945 GetTemporalUnit(isolate, round_to,
"smallestUnit", UnitGroup::kTime,
16946 Unit::kDay,
true, method_name, Unit::kDay),
16953 ToTemporalRoundingMode(isolate, round_to, RoundingMode::kHalfExpand,
16962 ToTemporalDateTimeRoundingIncrement(isolate, round_to,
smallest_unit),
16970 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
16971 .ToHandleChecked();
16978 isolate, temporal_date_time,
16992 {{temporal_date_time->iso_year(), temporal_date_time->iso_month(),
16993 temporal_date_time->iso_day()},
16994 {0, 0, 0, 0, 0, 0}},
17000 isolate, instant_start,
17001 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, dt_start,
17002 Disambiguation::kCompatible, method_name));
17011 {0, 0, 0, {1, 0, 0, 0, 0, 0, 0}}, method_name));
17016 if (day_length_ns->IsNegative() || !day_length_ns->ToBoolean()) {
17026 DateTimeRecord round_result = RoundISODateTime(
17028 {{temporal_date_time->iso_year(), temporal_date_time->iso_month(),
17029 temporal_date_time->iso_day()},
17030 {temporal_date_time->iso_hour(), temporal_date_time->iso_minute(),
17031 temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(),
17032 temporal_date_time->iso_microsecond(),
17033 temporal_date_time->iso_nanosecond()}},
17037 int64_t offset_nanoseconds;
17039 isolate, offset_nanoseconds,
17040 GetOffsetNanosecondsFor(isolate,
time_zone, instant, method_name),
17050 isolate, epoch_nanoseconds,
17051 InterpretISODateTimeOffset(
17052 isolate, round_result, OffsetBehaviour::kOption, offset_nanoseconds,
17053 time_zone, Disambiguation::kCompatible, Offset::kPrefer,
17054 MatchBehaviour::kMatchExactly, method_name));
17058 return CreateTemporalZonedDateTime(isolate, epoch_nanoseconds,
time_zone,
17060 .ToHandleChecked();
17067AddDurationToOrSubtractDurationFromZonedDateTime(
17068 Isolate* isolate, Arithmetic operation,
17074 double sign = operation == Arithmetic::kSubtract ? -1.0 : 1.0;
17083 TimeDurationRecord& time_duration = duration.
time_duration;
17105 time_duration.days *=
sign;
17106 time_duration.hours *=
sign;
17107 time_duration.minutes *=
sign;
17108 time_duration.seconds *=
sign;
17109 time_duration.milliseconds *=
sign;
17110 time_duration.microseconds *=
sign;
17111 time_duration.nanoseconds *=
sign;
17114 isolate, epoch_nanoseconds,
17116 options, method_name));
17120 return CreateTemporalZonedDateTime(isolate, epoch_nanoseconds,
time_zone,
17131 return AddDurationToOrSubtractDurationFromZonedDateTime(
17132 isolate, Arithmetic::kAdd, zoned_date_time, temporal_duration_like,
17133 options,
"Temporal.ZonedDateTime.prototype.add");
17140 return AddDurationToOrSubtractDurationFromZonedDateTime(
17141 isolate, Arithmetic::kSubtract, zoned_date_time, temporal_duration_like,
17142 options,
"Temporal.ZonedDateTime.prototype.subtract");
17149 Isolate* isolate, TimePreposition operation,
17152 const char* method_name) {
17155 double sign = operation == TimePreposition::kSince ? -1 : 1;
17159 isolate, other, ToTemporalZonedDateTime(isolate, other_obj, method_name));
17162 bool calendar_equals;
17164 isolate, calendar_equals,
17165 CalendarEqualsBool(isolate,
17169 if (!calendar_equals) {
17175 DifferenceSettings settings;
17178 GetDifferenceSettings(isolate, operation, options, UnitGroup::kDateTime,
17179 DisallowedUnitsInDifferenceSettings::kNone,
17180 Unit::kNanosecond, Unit::kHour, method_name),
17181 DirectHandle<JSTemporalDuration>());
17185 if (settings.largest_unit != Unit::kYear &&
17186 settings.largest_unit != Unit::kMonth &&
17187 settings.largest_unit != Unit::kWeek &&
17188 settings.largest_unit != Unit::kDay) {
17193 TimeDurationRecord balance_result = DifferenceInstant(
17194 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate),
17196 settings.rounding_increment, settings.smallest_unit,
17197 settings.largest_unit, settings.rounding_mode, method_name);
17202 return CreateTemporalDuration(
17207 {0,
sign * balance_result.hours,
sign * balance_result.minutes,
17208 sign * balance_result.seconds,
17209 sign * balance_result.milliseconds,
17210 sign * balance_result.microseconds,
17211 sign * balance_result.nanoseconds}})
17212 .ToHandleChecked();
17219 TimeZoneEquals(isolate,
17222 DirectHandle<JSTemporalDuration>());
17229 DirectHandle<JSReceiver> until_options;
17231 isolate, until_options,
17232 MergeLargestUnitOption(isolate, settings.options, settings.largest_unit));
17237 DurationRecord difference;
17239 isolate, difference,
17240 DifferenceZonedDateTime(
17241 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate),
17245 settings.largest_unit, until_options, method_name),
17246 DirectHandle<JSTemporalDuration>());
17255 DurationRecordWithRemainder round_result;
17257 isolate, round_result,
17258 RoundDuration(isolate, difference, settings.rounding_increment,
17259 settings.smallest_unit, settings.rounding_mode,
17260 zoned_date_time, method_name),
17261 DirectHandle<JSTemporalDuration>());
17271 AdjustRoundedDurationDays(isolate, round_result.record,
17272 settings.rounding_increment,
17273 settings.smallest_unit, settings.rounding_mode,
17274 zoned_date_time, method_name),
17275 DirectHandle<JSTemporalDuration>());
17282 return CreateTemporalDuration(isolate,
17293 .ToHandleChecked();
17303 return DifferenceTemporalZonedDateTime(
17304 isolate, TimePreposition::kUntil,
handle, other, options,
17305 "Temporal.ZonedDateTime.prototype.until");
17313 return DifferenceTemporalZonedDateTime(
17314 isolate, TimePreposition::kSince,
handle, other, options,
17315 "Temporal.ZonedDateTime.prototype.since");
17322 const char* method_name =
"Temporal.ZonedDateTime.prototype.getISOFields";
17323 Factory* factory = isolate->factory();
17329 isolate->factory()->NewJSObject(isolate->object_function());
17337 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate)));
17345 isolate, date_time,
17351 BuiltinTimeZoneGetOffsetStringFor(
17352 isolate,
time_zone, instant, method_name));
17354#define DEFINE_STRING_FIELD(obj, str, field) \
17355 CHECK(JSReceiver::CreateDataProperty(isolate, obj, factory->str##_string(), \
17356 field, Just(kThrowOnError)) \
17399 return SystemInstant(isolate);
17414 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
17415 .ToHandleChecked();
17420 GetOffsetNanosecondsFor(
17422 "Temporal.ZonedDateTime.prototype.offsetNanoseconds"),
17424 return isolate->factory()->NewNumberFromInt64(
result);
17437 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
17438 .ToHandleChecked();
17441 return BuiltinTimeZoneGetOffsetStringFor(
17442 isolate,
direct_handle(zoned_date_time->time_zone(), isolate), instant,
17443 "Temporal.ZonedDateTime.prototype.offset");
17450 const char* method_name =
"Temporal.ZonedDateTime.prototype.startOfDay";
17461 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
17462 .ToHandleChecked();
17467 isolate, temporal_date_time,
17476 isolate, start_date_time,
17479 {{temporal_date_time->iso_year(), temporal_date_time->iso_month(),
17480 temporal_date_time->iso_day()},
17481 {0, 0, 0, 0, 0, 0}},
17487 isolate, start_instant,
17488 BuiltinTimeZoneGetInstantFor(isolate,
time_zone, start_date_time,
17489 Disambiguation::kCompatible, method_name));
17492 return CreateTemporalZonedDateTime(
17506 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
17507 .ToHandleChecked();
17515 const char* method_name) {
17525 isolate,
direct_handle(zoned_date_time->nanoseconds(), isolate))
17526 .ToHandleChecked();
17531 direct_handle(zoned_date_time->calendar(), isolate), method_name);
17542 isolate, temporal_date_time,
17543 ZonedDateTimeToPlainDateTime(
17544 isolate, zoned_date_time,
17545 "Temporal.ZonedDateTime.prototype.toPlainDate"));
17548 return CreateTemporalDate(
17550 {temporal_date_time->iso_year(), temporal_date_time->iso_month(),
17551 temporal_date_time->iso_day()},
17561 isolate, temporal_date_time,
17562 ZonedDateTimeToPlainDateTime(
17563 isolate, zoned_date_time,
17564 "Temporal.ZonedDateTime.prototype.toPlainTime"));
17569 return CreateTemporalTime(
17571 {temporal_date_time->iso_hour(), temporal_date_time->iso_minute(),
17572 temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(),
17573 temporal_date_time->iso_microsecond(),
17574 temporal_date_time->iso_nanosecond()});
17581 return ZonedDateTimeToPlainDateTime(
17582 isolate, zoned_date_time,
17583 "Temporal.ZonedDateTime.prototype.toPlainDateTime");
17596 NewTypeError(MessageTemplate::kMethodInvokedOnWrongType,
17597 isolate->factory()->NewStringFromAsciiChecked(
17598 "Temporal.Instant")));
17603 isolate, epoch_nanoseconds,
17604 BigInt::FromObject(isolate, epoch_nanoseconds_obj));
17607 if (!IsValidEpochNanoseconds(isolate, epoch_nanoseconds)) {
17612 epoch_nanoseconds);
17624 scale == 1000000000);
17628 epoch_nanoseconds = bigint;
17631 isolate, epoch_nanoseconds,
17636 if (!IsValidEpochNanoseconds(isolate, epoch_nanoseconds)) {
17642MaybeDirectHandle<JSTemporalInstant> ScaleNumberToNanosecondsVerifyAndMake(
17643 Isolate* isolate, DirectHandle<Object> epoch_Xseconds, uint32_t
scale) {
17649 DirectHandle<BigInt> bigint;
17652 return ScaleNumberToNanosecondsVerifyAndMake(isolate, bigint,
scale);
17655MaybeDirectHandle<JSTemporalInstant> ScaleToNanosecondsVerifyAndMake(
17656 Isolate* isolate, DirectHandle<Object> epoch_Xseconds, uint32_t
scale) {
17659 DirectHandle<BigInt> bigint;
17661 BigInt::FromObject(isolate, epoch_Xseconds));
17662 return ScaleNumberToNanosecondsVerifyAndMake(isolate, bigint,
scale);
17671 return ScaleNumberToNanosecondsVerifyAndMake(isolate, epoch_seconds,
17687 return ScaleToNanosecondsVerifyAndMake(isolate, epoch_microseconds, 1000);
17694 return ScaleToNanosecondsVerifyAndMake(isolate, epoch_nanoseconds, 1);
17702 const char* method_name =
"Temporal.Instant.compare";
17706 ToTemporalInstant(isolate, one_obj, method_name));
17710 ToTemporalInstant(isolate, two_obj, method_name));
17713 return CompareEpochNanoseconds(isolate,
17729 ToTemporalInstant(isolate, other_obj,
17730 "Temporal.Instant.prototype.equals"));
17733 return isolate->factory()->ToBoolean(
17742 double dividend,
bool dividend_is_defined,
bool inclusive) {
17745 if (!dividend_is_defined) {
17747 maximum = std::numeric_limits<double>::infinity();
17749 }
else if (inclusive) {
17751 maximum = dividend;
17753 }
else if (dividend > 1) {
17755 maximum = dividend - 1;
17767 isolate->factory()->roundingIncrement_string(),
17781 if ((dividend_is_defined) && (std::fmod(dividend,
increment) != 0)) {
17791DirectHandle<BigInt> RoundTemporalInstant(Isolate* isolate,
17792 DirectHandle<BigInt> ns,
17797 double increment_ns;
17805 case Unit::kMinute:
17810 case Unit::kSecond:
17815 case Unit::kMillisecond:
17820 case Unit::kMicrosecond:
17826 case Unit::kNanosecond:
17835 return RoundNumberToIncrementAsIfPositive(isolate, ns, increment_ns,
17846 const char* method_name =
"Temporal.Instant.prototype.round";
17847 Factory* factory = isolate->factory();
17851 if (IsUndefined(*round_to_obj)) {
17857 if (IsString(*round_to_obj)) {
17865 factory->smallestUnit_string(),
17880 GetTemporalUnit(isolate, round_to,
"smallestUnit", UnitGroup::kTime,
17881 Unit::kNotPresent,
true, method_name),
17888 ToTemporalRoundingMode(isolate, round_to, RoundingMode::kHalfExpand,
17899 case Unit::kMinute:
17904 case Unit::kSecond:
17909 case Unit::kMillisecond:
17914 case Unit::kMicrosecond:
17919 case Unit::kNanosecond:
17921 maximum = kNsPerDay;
17932 ToTemporalRoundingIncrement(isolate, round_to, maximum,
true,
true),
17949 if (IsJSTemporalInstant(*item)) {
17956 return ToTemporalInstant(isolate, item,
"Temporal.Instant.from");
17964 const char* method_name =
"Temporal.Instant.prototype.toZonedDateTime";
17965 Factory* factory = isolate->factory();
17969 if (!IsJSReceiver(*item_obj)) {
17977 isolate, calendar_like,
17980 if (IsUndefined(*calendar_like)) {
17993 isolate, temporal_time_zone_like,
17996 if (IsUndefined(*calendar_like)) {
18008 return CreateTemporalZonedDateTime(
18019 const char* method_name) {
18027 if (IsUndefined(*time_zone_obj)) {
18029 output_time_zone = CreateTemporalTimeZoneUTC(isolate);
18031 DCHECK(IsJSReceiver(*time_zone_obj));
18036 DirectHandle<JSTemporalCalendar> iso_calendar =
18041 DirectHandle<JSTemporalPlainDateTime> date_time;
18043 isolate, date_time,
18045 isolate, output_time_zone, instant, iso_calendar, method_name));
18052 DirectHandle<String> date_time_string;
18054 isolate, date_time_string,
18055 TemporalDateTimeToString(
18057 {{date_time->iso_year(), date_time->iso_month(),
18058 date_time->iso_day()},
18059 {date_time->iso_hour(), date_time->iso_minute(),
18060 date_time->iso_second(), date_time->iso_millisecond(),
18061 date_time->iso_microsecond(), date_time->iso_nanosecond()}},
18064 builder.AppendString(date_time_string);
18067 if (IsUndefined(*time_zone_obj)) {
18069 builder.AppendCharacter(
'Z');
18072 DCHECK(IsJSReceiver(*time_zone_obj));
18078 isolate, offset_ns,
18079 GetOffsetNanosecondsFor(isolate,
time_zone, instant, method_name),
18080 DirectHandle<String>());
18082 DirectHandle<String> time_zone_string =
18083 FormatISOTimeZoneOffsetString(isolate, offset_ns);
18084 builder.AppendString(time_zone_string);
18088 return builder.Finish();
18100 return TemporalInstantToString(
18101 isolate, instant, isolate->factory()->undefined_value(), Precision::kAuto,
18102 "Temporal.Instant.prototype.toJSON");
18109 const char* method_name =
"Temporal.Instant.prototype.toLocaleString";
18110#ifdef V8_INTL_SUPPORT
18112 options, method_name);
18114 return TemporalInstantToString(isolate, instant,
18115 isolate->factory()->undefined_value(),
18116 Precision::kAuto, method_name);
18124 Factory* factory = isolate->factory();
18125 const char* method_name =
"Temporal.Instant.prototype.toString";
18149 ToSecondsStringPrecision(isolate, options, method_name),
18155 ToTemporalRoundingMode(isolate, options, RoundingMode::kTrunc,
18170 return TemporalInstantToString(isolate, rounded_instant,
time_zone,
18172 "Temporal.Instant.prototype.toString");
18181 Factory* factory = isolate->factory();
18185 if (IsJSReceiver(*item_obj)) {
18190 isolate, time_zone_property,
18193 if (!IsUndefined(*time_zone_property)) {
18195 item_obj = time_zone_property;
18203 isolate, item_obj,
"Temporal.Instant.prototype.toZonedDateTimeISO"));
18209 return CreateTemporalZonedDateTime(
18218 Isolate* isolate, Arithmetic operation,
18223 double sign = operation == Arithmetic::kSubtract ? -1.0 : 1.0;
18234 TimeDurationRecord& time_duration = duration.
time_duration;
18235 if (time_duration.days != 0 || duration.
months != 0 || duration.
weeks != 0 ||
18236 duration.
years != 0) {
18246 DirectHandle<BigInt> ns;
18250 isolate, DirectHandle<BigInt>(
handle->nanoseconds(), isolate),
18251 {0, sign * time_duration.hours, sign * time_duration.minutes,
18252 sign * time_duration.seconds, sign * time_duration.milliseconds,
18253 sign * time_duration.microseconds,
18254 sign * time_duration.nanoseconds}));
18263 case RoundingMode::kCeil:
18264 return RoundingMode::kFloor;
18266 case RoundingMode::kFloor:
18267 return RoundingMode::kCeil;
18269 case RoundingMode::kHalfCeil:
18270 return RoundingMode::kHalfFloor;
18272 case RoundingMode::kHalfFloor:
18273 return RoundingMode::kHalfCeil;
18281Maybe<DifferenceSettings> GetDifferenceSettings(
18282 Isolate* isolate, TimePreposition operation, DirectHandle<Object> options,
18283 UnitGroup unit_group, DisallowedUnitsInDifferenceSettings disallowed_units,
18284 Unit fallback_smallest_unit, Unit smallest_largest_default_unit,
18285 const char* method_name) {
18286 DifferenceSettings
record;
18294 isolate,
record.smallest_unit,
18295 GetTemporalUnit(isolate,
record.options,
"smallestUnit", unit_group,
18296 fallback_smallest_unit,
18297 fallback_smallest_unit == Unit::kNotPresent, method_name),
18300 if (disallowed_units == DisallowedUnitsInDifferenceSettings::kWeekAndDay) {
18301 if (
record.smallest_unit == Unit::kWeek) {
18304 NewRangeError(MessageTemplate::kInvalidUnit,
18305 isolate->factory()->smallestUnit_string(),
18306 isolate->factory()->week_string()),
18309 if (
record.smallest_unit == Unit::kDay) {
18312 NewRangeError(MessageTemplate::kInvalidUnit,
18313 isolate->factory()->smallestUnit_string(),
18314 isolate->factory()->day_string()),
18320 Unit default_largest_unit = LargerOfTwoTemporalUnits(
18321 smallest_largest_default_unit,
record.smallest_unit);
18325 isolate,
record.largest_unit,
18326 GetTemporalUnit(isolate,
record.options,
"largestUnit", unit_group,
18327 Unit::kAuto,
false, method_name),
18330 if (disallowed_units == DisallowedUnitsInDifferenceSettings::kWeekAndDay) {
18331 if (
record.largest_unit == Unit::kWeek) {
18334 NewRangeError(MessageTemplate::kInvalidUnit,
18335 isolate->factory()->largestUnit_string(),
18336 isolate->factory()->week_string()),
18339 if (
record.largest_unit == Unit::kDay) {
18342 NewRangeError(MessageTemplate::kInvalidUnit,
18343 isolate->factory()->largestUnit_string(),
18344 isolate->factory()->day_string()),
18349 if (
record.largest_unit == Unit::kAuto) {
18350 record.largest_unit = default_largest_unit;
18354 if (LargerOfTwoTemporalUnits(
record.largest_unit,
record.smallest_unit) !=
18358 NewRangeError(MessageTemplate::kInvalidArgumentForTemporal,
18359 isolate->factory()->largestUnit_string()),
18364 isolate,
record.rounding_mode,
18365 ToTemporalRoundingMode(isolate,
record.options, RoundingMode::kTrunc,
18369 if (operation == TimePreposition::kSince) {
18371 record.rounding_mode = NegateTemporalRoundingMode(
record.rounding_mode);
18376 MaximumTemporalDurationRoundingIncrement(
record.smallest_unit);
18380 isolate,
record.rounding_increment,
18381 ToTemporalRoundingIncrement(isolate,
record.options, maximum.value,
18382 maximum.defined,
false),
18391TimeDurationRecord DifferenceInstant(Isolate* isolate, DirectHandle<BigInt> ns1,
18392 DirectHandle<BigInt> ns2,
18396 const char* method_name) {
18404 DirectHandle<BigInt> diff =
18409 DirectHandle<BigInt> nanoseconds_in_a_hour =
18413 BigInt::Divide(isolate, diff, nanoseconds_in_a_hour).ToHandleChecked()));
18416 .ToHandleChecked()));
18417 DurationRecordWithRemainder round_record =
18419 isolate, {0, 0, 0, {0, diff_hours, 0, 0, 0, 0, diff_nanoseconds}},
18423 DCHECK_EQ(0, round_record.record.time_duration.days);
18429 isolate->factory()->undefined_value(),
18430 round_record.record.time_duration, method_name)
18435MaybeDirectHandle<JSTemporalDuration> DifferenceTemporalInstant(
18436 Isolate* isolate, TimePreposition operation,
18437 DirectHandle<JSTemporalInstant> instant, DirectHandle<Object> other_obj,
18438 DirectHandle<Object> options,
const char* method_name) {
18441 double sign = operation == TimePreposition::kSince ? -1 : 1;
18443 DirectHandle<JSTemporalInstant> other;
18445 isolate, other, ToTemporalInstant(isolate, other_obj, method_name));
18448 DifferenceSettings settings;
18451 GetDifferenceSettings(isolate, operation, options, UnitGroup::kTime,
18452 DisallowedUnitsInDifferenceSettings::kNone,
18453 Unit::kNanosecond, Unit::kSecond, method_name),
18454 DirectHandle<JSTemporalDuration>());
18459 TimeDurationRecord
result = DifferenceInstant(
18461 direct_handle(other->nanoseconds(), isolate), settings.rounding_increment,
18462 settings.smallest_unit, settings.largest_unit, settings.rounding_mode,
18468 return CreateTemporalDuration(
18475 .ToHandleChecked();
18484 return AddDurationToOrSubtractDurationFromInstant(
18485 isolate, Arithmetic::kAdd,
handle, temporal_duration_like,
18486 "Temporal.Instant.prototype.add");
18494 return AddDurationToOrSubtractDurationFromInstant(
18495 isolate, Arithmetic::kSubtract,
handle, temporal_duration_like,
18496 "Temporal.Instant.prototype.subtract");
18504 return DifferenceTemporalInstant(isolate, TimePreposition::kUntil,
handle,
18506 "Temporal.Instant.prototype.until");
18514 return DifferenceTemporalInstant(isolate, TimePreposition::kSince,
handle,
18516 "Temporal.Instant.prototype.since");
18518namespace temporal {
18524 Factory* factory = isolate->factory();
18526 for (
int i = 0;
i < fields_name->length();
i++) {
18531 return isolate->factory()->true_value();
18536 if (!(
String::Equals(isolate, next_value, factory->year_string()) ||
18538 String::Equals(isolate, next_value, factory->monthCode_string()) ||
18541 String::Equals(isolate, next_value, factory->minute_string()) ||
18542 String::Equals(isolate, next_value, factory->second_string()) ||
18543 String::Equals(isolate, next_value, factory->millisecond_string()) ||
18544 String::Equals(isolate, next_value, factory->microsecond_string()) ||
18545 String::Equals(isolate, next_value, factory->nanosecond_string()))) {
18546 return isolate->factory()->true_value();
18548 return isolate->factory()->false_value();
18563 return BuiltinTimeZoneGetInstantFor(isolate,
time_zone, date_time,
18564 Disambiguation::kCompatible, method_name);
interpreter::OperandScale scale
static MaybeHandle< BigInt > Remainder(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
static ComparisonResult CompareToBigInt(DirectHandle< BigInt > x, DirectHandle< BigInt > y)
static MaybeHandle< BigInt > Multiply(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
static DirectHandle< Number > ToNumber(Isolate *isolate, DirectHandle< BigInt > x)
static MaybeHandle< BigInt > Divide(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
static MaybeHandle< String > ToString(Isolate *isolate, DirectHandle< BigInt > bigint, int radix=10, ShouldThrow should_throw=kThrowOnError)
static MaybeHandle< BigInt > Increment(Isolate *isolate, DirectHandle< BigInt > x)
static bool EqualToBigInt(Tagged< BigInt > x, Tagged< BigInt > y)
static V8_EXPORT_PRIVATE Handle< BigInt > FromUint64(Isolate *isolate, uint64_t n)
static MaybeHandle< BigInt > Decrement(Isolate *isolate, DirectHandle< BigInt > x)
static Handle< BigInt > UnaryMinus(Isolate *isolate, DirectHandle< BigInt > x)
static V8_EXPORT_PRIVATE Handle< BigInt > FromInt64(Isolate *isolate, int64_t n)
static MaybeHandle< BigInt > Add(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
static ComparisonResult CompareToNumber(DirectHandle< BigInt > x, DirectHandle< Object > y)
static MaybeHandle< BigInt > Subtract(Isolate *isolate, DirectHandle< BigInt > x, DirectHandle< BigInt > y)
static V8_EXPORT_PRIVATE MaybeHandle< BigInt > FromNumber(Isolate *isolate, DirectHandle< Object > number)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > Call(Isolate *isolate, DirectHandle< Object > callable, DirectHandle< Object > receiver, base::Vector< const DirectHandle< Object > > args)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > CallBuiltin(Isolate *isolate, DirectHandle< JSFunction > builtin, DirectHandle< Object > receiver, base::Vector< const DirectHandle< Object > > args)
Handle< Number > NewNumber(double value)
Handle< FixedArray > NewFixedArray(int length, AllocationType allocation=AllocationType::kYoung)
Handle< JSObject > NewJSObjectWithNullProto()
Handle< JSObject > NewJSObject(DirectHandle< JSFunction > constructor, AllocationType allocation=AllocationType::kYoung, NewJSObjectType=NewJSObjectType::kNoAPIWrapper)
Handle< JSArray > NewJSArrayWithElements(DirectHandle< FixedArrayBase > elements, ElementsKind elements_kind, int length, AllocationType allocation=AllocationType::kYoung)
static HandleType< FixedArray > RightTrimOrEmpty(Isolate *isolate, HandleType< FixedArray > array, int new_length)
static V8_EXPORT_PRIVATE HandleType< FixedArray > SetAndGrow(Isolate *isolate, HandleType< FixedArray > array, int index, DirectHandle< Object > value)
V8_INLINE void AppendInt(int i)
MaybeDirectHandle< String > Finish()
V8_INLINE void AppendCharacter(uint8_t c)
static V8_WARN_UNUSED_RESULT MaybeHandle< String > ConvertToLower(Isolate *isolate, DirectHandle< String > s)
static DirectHandleVector< BigInt > GetTimeZonePossibleOffsetNanoseconds(Isolate *isolate, int32_t time_zone_index, DirectHandle< BigInt > nanosecond_epoch)
static int32_t GetTimeZoneIndex(Isolate *isolate, DirectHandle< String > identifier)
static DirectHandle< Object > GetTimeZoneOffsetTransitionNanoseconds(Isolate *isolate, int32_t time_zone_index, DirectHandle< BigInt > nanosecond_epoch, Transition transition)
static DirectHandle< String > DefaultTimeZone(Isolate *isolate)
static V8_WARN_UNUSED_RESULT bool IsValidTimeZoneName(const icu::TimeZone &tz)
static V8_WARN_UNUSED_RESULT std::string TimeZoneIdFromIndex(int32_t index)
static V8_WARN_UNUSED_RESULT MaybeHandle< String > CanonicalizeTimeZoneName(Isolate *isolate, DirectHandle< String > identifier)
static int64_t GetTimeZoneOffsetNanoseconds(Isolate *isolate, int32_t time_zone_index, DirectHandle< BigInt > nanosecond_epoch)
static V8_WARN_UNUSED_RESULT Maybe< bool > CreateDataProperty(Isolate *isolate, DirectHandle< JSReceiver > object, DirectHandle< Name > key, DirectHandle< Object > value, Maybe< ShouldThrow > should_throw)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(Isolate *isolate, DirectHandle< JSReceiver > receiver, const char *key)
static V8_WARN_UNUSED_RESULT Maybe< bool > SetOrCopyDataProperties(Isolate *isolate, DirectHandle< JSReceiver > target, DirectHandle< Object > source, PropertiesEnumerationMode mode, base::Vector< DirectHandle< Object > > excluded_properties={}, bool use_set=true)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > DateAdd(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > date, DirectHandle< Object > durations, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, const char *method_name)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > DaysInWeek(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Year(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > MonthCode(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > MonthsInYear(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > DateFromFields(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > fields, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > DaysInMonth(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > DaysInYear(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Day(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainMonthDay > MonthDayFromFields(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > fields, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > DayOfWeek(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > DateUntil(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > one, DirectHandle< Object > two, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > MergeFields(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > fields, DirectHandle< Object > additional_fields)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > WeekOfYear(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalCalendar > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > identifier)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > YearMonthFromFields(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > fields, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > DayOfYear(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > InLeapYear(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Month(Isolate *isolate, DirectHandle< JSTemporalCalendar > calendar, DirectHandle< Object > temporal_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Negated(Isolate *isolate, DirectHandle< JSTemporalDuration > duration)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToJSON(Isolate *isolate, DirectHandle< JSTemporalDuration > duration)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalDuration > duration, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Add(Isolate *isolate, DirectHandle< JSTemporalDuration > duration, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > From(Isolate *isolate, DirectHandle< Object > item)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > Blank(Isolate *isolate, DirectHandle< JSTemporalDuration > duration)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Abs(Isolate *isolate, DirectHandle< JSTemporalDuration > duration)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > years, DirectHandle< Object > months, DirectHandle< Object > weeks, DirectHandle< Object > days, DirectHandle< Object > hours, DirectHandle< Object > minutes, DirectHandle< Object > seconds, DirectHandle< Object > milliseconds, DirectHandle< Object > microseconds, DirectHandle< Object > nanoseconds)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Sign(Isolate *isolate, DirectHandle< JSTemporalDuration > duration)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Subtract(Isolate *isolate, DirectHandle< JSTemporalDuration > duration, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Compare(Isolate *isolate, DirectHandle< Object > one, DirectHandle< Object > two, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > With(Isolate *isolate, DirectHandle< JSTemporalDuration > duration, DirectHandle< Object > temporal_duration_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Round(Isolate *isolate, DirectHandle< JSTemporalDuration > duration, DirectHandle< Object > round_to_obj)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > Total(Isolate *isolate, DirectHandle< JSTemporalDuration > duration, DirectHandle< Object > total_of)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToLocaleString(Isolate *isolate, DirectHandle< JSTemporalDuration > duration, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > ToZonedDateTime(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > item)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToJSON(Isolate *isolate, DirectHandle< JSTemporalInstant > instant)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > epoch_nanoseconds)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > Subtract(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > temporal_duration_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > ToZonedDateTimeISO(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > item)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > Equals(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > other)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > Add(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > temporal_duration_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > FromEpochNanoseconds(Isolate *isolate, DirectHandle< Object > epoch_nanoseconds)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > From(Isolate *isolate, DirectHandle< Object > item)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Since(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > Round(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > round_to)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToLocaleString(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > FromEpochMilliseconds(Isolate *isolate, DirectHandle< Object > epoch_milliseconds)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > Now(Isolate *isolate)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > FromEpochMicroseconds(Isolate *isolate, DirectHandle< Object > epoch_microseconds)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > FromEpochSeconds(Isolate *isolate, DirectHandle< Object > epoch_seconds)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Compare(Isolate *isolate, DirectHandle< Object > one, DirectHandle< Object > two)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Until(Isolate *isolate, DirectHandle< JSTemporalInstant > instant, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > WithCalendar(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > calendar_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToJSON(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > WithPlainTime(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > temporal_time_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > iso_year, DirectHandle< Object > iso_month, DirectHandle< Object > iso_day, DirectHandle< Object > hour, DirectHandle< Object > minute, DirectHandle< Object > second, DirectHandle< Object > millisecond, DirectHandle< Object > microsecond, DirectHandle< Object > nanosecond, DirectHandle< Object > calendar_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Since(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > Subtract(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > Equals(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > plain_date, DirectHandle< Object > other)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > ToZonedDateTime(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > temporal_time_zone_like, DirectHandle< Object > options_obj)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > Add(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToLocaleString(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Until(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > Round(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > round_to)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > Now(Isolate *isolate, DirectHandle< Object > calendar_like, DirectHandle< Object > temporal_time_zone_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > With(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > temporal_date_time_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > NowISO(Isolate *isolate, DirectHandle< Object > temporal_time_zone_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > ToPlainYearMonth(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > WithPlainDate(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > temporal_date_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > ToPlainTime(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Compare(Isolate *isolate, DirectHandle< Object > one, DirectHandle< Object > two)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > From(Isolate *isolate, DirectHandle< Object > item, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > ToPlainDate(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainMonthDay > ToPlainMonthDay(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > GetISOFields(Isolate *isolate, DirectHandle< JSTemporalPlainDateTime > date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Since(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > Subtract(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Until(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Compare(Isolate *isolate, DirectHandle< Object > one, DirectHandle< Object > two)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToJSON(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > iso_year, DirectHandle< Object > iso_month, DirectHandle< Object > iso_day, DirectHandle< Object > calendar_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > Equals(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > other)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > NowISO(Isolate *isolate, DirectHandle< Object > temporal_time_zone_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainMonthDay > ToPlainMonthDay(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > GetISOFields(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > ToZonedDateTime(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > item)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > From(Isolate *isolate, DirectHandle< Object > item, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > With(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > Add(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > Now(Isolate *isolate, DirectHandle< Object > calendar_like, DirectHandle< Object > temporal_time_zone_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > WithCalendar(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > calendar_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > ToPlainDateTime(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > temporal_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > ToPlainYearMonth(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToLocaleString(Isolate *isolate, DirectHandle< JSTemporalPlainDate > plain_date, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainMonthDay > With(Isolate *isolate, DirectHandle< JSTemporalPlainMonthDay > month_day, DirectHandle< Object > temporal_month_day_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToLocaleString(Isolate *isolate, DirectHandle< JSTemporalPlainMonthDay > plain_date, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalPlainMonthDay > month_day, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > ToPlainDate(Isolate *isolate, DirectHandle< JSTemporalPlainMonthDay > month_day, DirectHandle< Object > item)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainMonthDay > From(Isolate *isolate, DirectHandle< Object > item, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToJSON(Isolate *isolate, DirectHandle< JSTemporalPlainMonthDay > month_day)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > Equals(Isolate *isolate, DirectHandle< JSTemporalPlainMonthDay > month_day, DirectHandle< Object > other)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > GetISOFields(Isolate *isolate, DirectHandle< JSTemporalPlainMonthDay > month_day)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainMonthDay > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > iso_month, DirectHandle< Object > iso_day, DirectHandle< Object > calendar_like, DirectHandle< Object > reference_iso_year)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > GetISOFields(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Until(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Compare(Isolate *isolate, DirectHandle< Object > one, DirectHandle< Object > two)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > ToPlainDateTime(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > temporal_date)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > Round(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > round_to)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > With(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > temporal_time_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > Subtract(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > temporal_duration_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > NowISO(Isolate *isolate, DirectHandle< Object > temporal_time_zone_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToLocaleString(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > ToZonedDateTime(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > item)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > hour, DirectHandle< Object > minute, DirectHandle< Object > second, DirectHandle< Object > millisecond, DirectHandle< Object > microsecond, DirectHandle< Object > nanosecond)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToJSON(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > Add(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > temporal_duration_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > From(Isolate *isolate, DirectHandle< Object > item, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Since(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_time, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > Equals(Isolate *isolate, DirectHandle< JSTemporalPlainTime > plain_date, DirectHandle< Object > other)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > With(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month, DirectHandle< Object > temporal_year_month_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Since(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > GetISOFields(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToJSON(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > ToPlainDate(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month, DirectHandle< Object > item)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToLocaleString(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > plain_date, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > Equals(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month, DirectHandle< Object > other)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > From(Isolate *isolate, DirectHandle< Object > item, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > iso_year, DirectHandle< Object > iso_month, DirectHandle< Object > calendar_like, DirectHandle< Object > reference_iso_day)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > Subtract(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Until(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Compare(Isolate *isolate, DirectHandle< Object > one, DirectHandle< Object > two)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > Add(Isolate *isolate, DirectHandle< JSTemporalPlainYearMonth > year_month, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalTimeZone > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > identifier)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > GetPlainDateTimeFor(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, DirectHandle< Object > instance, DirectHandle< Object > calendar_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > GetOffsetNanosecondsFor(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, DirectHandle< Object > instance)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > GetInstantFor(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, DirectHandle< Object > dateTime, DirectHandle< Object > options)
static MaybeDirectHandle< Object > ToString(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, const char *method_name)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalTimeZone > Now(Isolate *isolate)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > GetPreviousTransition(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, DirectHandle< Object > starting_point)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > GetOffsetStringFor(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, DirectHandle< Object > instance)
MaybeDirectHandle< String > id(Isolate *isolate) const
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > GetNextTransition(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, DirectHandle< Object > starting_point)
int64_t offset_nanoseconds() const
int32_t time_zone_index() const
void set_offset_nanoseconds(int64_t offset_nanoseconds)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSArray > GetPossibleInstantsFor(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, DirectHandle< Object > date_time)
static constexpr int32_t kUTCTimeZoneIndex
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Since(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > date_time, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToLocaleString(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > locales, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > StartOfDay(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > Subtract(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > WithPlainDate(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > plain_date_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > WithPlainTime(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > plain_time_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > Offset(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToString(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Oddball > Equals(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > other)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToJSON(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDateTime > ToPlainDateTime(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > With(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > temporal_zoned_date_time_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > NowISO(Isolate *isolate, DirectHandle< Object > temporal_time_zone_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSReceiver > GetISOFields(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > WithCalendar(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > calendar_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainDate > ToPlainDate(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > HoursInDay(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > Add(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > temporal_duration_like, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainYearMonth > ToPlainYearMonth(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainMonthDay > ToPlainMonthDay(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalInstant > ToInstant(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > OffsetNanoseconds(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalPlainTime > ToPlainTime(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Smi > Compare(Isolate *isolate, DirectHandle< Object > one, DirectHandle< Object > two)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalDuration > Until(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > date_time, DirectHandle< Object > other, DirectHandle< Object > options)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > Constructor(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< Object > epoch_nanoseconds, DirectHandle< Object > time_zone_like, DirectHandle< Object > calendar_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > WithTimeZone(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > time_zone_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > Now(Isolate *isolate, DirectHandle< Object > calendar_like, DirectHandle< Object > temporal_time_zone_like)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > Round(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< Object > round_to)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< JSTemporalZonedDateTime > From(Isolate *isolate, DirectHandle< Object > item, DirectHandle< Object > options)
static MaybeHandle< FixedArray > GetKeys(Isolate *isolate, DirectHandle< JSReceiver > object, KeyCollectionMode mode, PropertyFilter filter, GetKeysConversion keys_conversion=GetKeysConversion::kKeepNumbers, bool is_for_in=false, bool skip_indices=false)
V8_INLINE DirectHandle< T > ToHandleChecked() const
static V8_WARN_UNUSED_RESULT HandleType< String >::MaybeType ToString(Isolate *isolate, HandleType< T > input)
static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetPropertyOrElement(Isolate *isolate, DirectHandle< JSAny > object, DirectHandle< Name > name)
static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ToNumber(Isolate *isolate, HandleType< T > input)
static V8_WARN_UNUSED_RESULT HandleType< Number >::MaybeType ToInteger(Isolate *isolate, HandleType< T > input)
static V8_WARN_UNUSED_RESULT HandleType< JSReceiver >::MaybeType ToObject(Isolate *isolate, HandleType< T > object, const char *method_name=nullptr)
static double NumberValue(Tagged< Number > obj)
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< Object > GetMethod(Isolate *isolate, DirectHandle< JSReceiver > receiver, DirectHandle< Name > name)
V8_EXPORT_PRIVATE static V8_WARN_UNUSED_RESULT MaybeHandle< Object > GetProperty(LookupIterator *it, bool is_global_reference=false)
static constexpr Tagged< Smi > FromInt(int value)
static constexpr Tagged< Smi > zero()
static V8_EXPORT_PRIVATE Handle< StringSet > New(Isolate *isolate)
static V8_EXPORT_PRIVATE Handle< StringSet > Add(Isolate *isolate, Handle< StringSet > stringset, DirectHandle< String > name)
static V8_INLINE HandleType< String > Flatten(Isolate *isolate, HandleType< T > string, AllocationType allocation=AllocationType::kYoung)
bool Equals(Tagged< String > other) const
static V8_EXPORT_PRIVATE v8::Platform * GetCurrentPlatform()
#define THROW_NEW_ERROR_RETURN_VALUE(isolate, call, value)
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call)
#define THROW_NEW_ERROR(isolate, call)
#define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
#define MAYBE_RETURN_ON_EXCEPTION_VALUE(isolate, call, value)
#define MAYBE_RETURN(call, value)
#define MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)
base::Vector< const DirectHandle< Object > > args
DirectHandle< Object > new_target
ArrayReduceDirection direction
#define ORDINARY_CREATE_FROM_CONSTRUCTOR(obj, target, new_target, T)
#define EXTRACT_CALENDAR(T, obj)
#define CONSTRUCTOR(name)
#define DEFINE_STRING_FIELD(obj, str, field)
DirectHandle< JSReceiver > options
#define DEFINE_INT_FIELD(obj, str, field, item)
double rounding_increment
#define CALENDAR_ABSTRACT_OPERATION_INT_ACTION(Name, name, Action)
DirectHandle< Object > offset_string
#define NEW_TEMPORAL_INVALID_ARG_TYPE_ERROR()
#define NEW_TEMPORAL_INVALID_ARG_RANGE_ERROR()
DirectHandle< JSTemporalPlainDate > relative_to
#define TEMPORAL_ENTER_FUNC()
#define THROW_INVALID_RANGE(T)
#define CALENDAR_ABSTRACT_OPERATION(Name, property)
DirectHandle< Object > calendar
#define TO_INT_THROW_ON_INFTY(name, T)
RoundingMode rounding_mode
ZoneVector< RpoNumber > & result
#define DEFINE_LAZY_LEAKY_OBJECT_GETTER(T, FunctionName,...)
int SNPrintF(Vector< char > str, const char *format,...)
constexpr Vector< T > VectorOf(T *start, size_t size)
Maybe< DurationRecord > ToTemporalDurationRecord(Isolate *isolate, DirectHandle< Object > temporal_duration_like_obj, const char *method_name)
MaybeDirectHandle< JSTemporalTimeZone > CreateTemporalTimeZone(Isolate *isolate, DirectHandle< String > identifier)
MaybeDirectHandle< Object > InvokeCalendarMethod(Isolate *isolate, DirectHandle< JSReceiver > calendar, DirectHandle< String > name, DirectHandle< JSReceiver > date_like)
MaybeDirectHandle< JSTemporalPlainDateTime > CreateTemporalDateTime(Isolate *isolate, const DateTimeRecord &date_time, DirectHandle< JSReceiver > calendar)
MaybeDirectHandle< JSTemporalInstant > CreateTemporalInstant(Isolate *isolate, DirectHandle< JSFunction > target, DirectHandle< HeapObject > new_target, DirectHandle< BigInt > epoch_nanoseconds)
MaybeDirectHandle< JSTemporalCalendar > GetBuiltinCalendar(Isolate *isolate, DirectHandle< String > id)
MaybeDirectHandle< JSTemporalInstant > BuiltinTimeZoneGetInstantForCompatible(Isolate *isolate, DirectHandle< JSReceiver > time_zone, DirectHandle< JSTemporalPlainDateTime > date_time, const char *method_name)
MaybeDirectHandle< JSReceiver > ToTemporalCalendar(Isolate *isolate, DirectHandle< Object > temporal_calendar_like, const char *method_name)
MaybeDirectHandle< JSTemporalDuration > ToTemporalDuration(Isolate *isolate, DirectHandle< Object > item, const char *method_name)
Maybe< DurationRecord > ToPartialDuration(Isolate *isolate, DirectHandle< Object > temporal_duration_like_obj, const DurationRecord &input)
Maybe< bool > IterateDurationRecordFieldsTable(Isolate *isolate, DirectHandle< JSReceiver > temporal_duration_like, Maybe< bool >(*RowFunction)(Isolate *, DirectHandle< JSReceiver > temporal_duration_like, DirectHandle< String >, double *), DurationRecord *record)
bool IsValidDuration(Isolate *isolate, const DurationRecord &dur)
MaybeDirectHandle< JSTemporalPlainTime > ToTemporalTime(Isolate *isolate, DirectHandle< Object > item_obj, const char *method_name, ShowOverflow overflow=ShowOverflow::kConstrain)
MaybeDirectHandle< Oddball > IsInvalidTemporalCalendarField(Isolate *isolate, DirectHandle< String > next_value, DirectHandle< FixedArray > fields_name)
MaybeDirectHandle< JSReceiver > ToTemporalTimeZone(Isolate *isolate, DirectHandle< Object > temporal_time_zone_like, const char *method_name)
Maybe< TimeRecord > RegulateTime(Isolate *isolate, const TimeRecord &time, ShowOverflow overflow)
DirectHandle< JSTemporalCalendar > GetISO8601Calendar(Isolate *isolate)
MaybeDirectHandle< JSTemporalPlainDateTime > BuiltinTimeZoneGetPlainDateTimeFor(Isolate *isolate, DirectHandle< JSReceiver > time_zone, DirectHandle< JSTemporalInstant > instant, DirectHandle< JSReceiver > calendar, const char *method_name)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
double MakeDate(double day, double time)
constexpr double kMaxSafeInteger
bool IsNaN(Tagged< Object > obj)
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
bool IsNumber(Tagged< Object > obj)
Maybe< double > GetNumberOptionAsDouble(Isolate *isolate, DirectHandle< JSReceiver > options, DirectHandle< String > property, double default_value)
constexpr AddrMode Offset
MaybeDirectHandle< JSReceiver > GetOptionsObject(Isolate *isolate, DirectHandle< Object > options, const char *method_name)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
MaybeDirectHandle< Object > GetTransition(Isolate *isolate, DirectHandle< JSTemporalTimeZone > time_zone, DirectHandle< Object > starting_point_obj, const char *method_name)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
MaybeDirectHandle< JSArray > GetIANATimeZoneEpochValueAsArrayOfInstant(Isolate *isolate, int32_t time_zone_index, const DateTimeRecord &date_time)
MaybeDirectHandle< T > ZonedDateTimeToPlainYearMonthOrMonthDay(Isolate *isolate, DirectHandle< JSTemporalZonedDateTime > zoned_date_time, DirectHandle< String > field_name_1, DirectHandle< String > field_name_2, const char *method_name)
double MakeDay(double year, double month, double date)
int32_t NumberToInt32(Tagged< Object > number)
double MakeTime(double hour, double min, double sec, double ms)
V8_INLINE constexpr bool IsHeapObject(TaggedImpl< kRefType, StorageType > obj)
static bool IsMinusZero(double value)
constexpr int AsciiAlphaToLower(base::uc32 c)
Maybe< bool > GetStringOption(Isolate *isolate, DirectHandle< JSReceiver > options, const char *property, const std::vector< const char * > &values, const char *method_name, std::unique_ptr< char[]> *result)
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset IsNull(value)||IsJSProxy(value)||IsWasmObject(value)||(IsJSObject(value) &&(HeapLayout
second_parts OffsetMillisecondsOrTimeZoneIndex offset_milliseconds_or_time_zone_index
MaybeDirectHandle< JSArray > GetIANATimeZoneEpochValueAsArrayOfInstantForUTC(Isolate *isolate, const DateTimeRecord &date_time)
template const char * string
MaybeDirectHandle< R > ToPlain(Isolate *isolate, DirectHandle< T > t, DirectHandle< String > f1, DirectHandle< String > f2)
second_parts offset_milliseconds
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Maybe< T > Just(const T &t)
#define DCHECK_LE(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
static constexpr int32_t kEmpty
static int32_t Sign(const DurationRecord &dur)
TimeDurationRecord time_duration
static Maybe< TimeDurationRecord > Create(Isolate *isolate, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds)
#define V8_WARN_UNUSED_RESULT