mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:47:44 +00:00
LibJS: Require 'T' prefix for ambiguous time-only strings
This is a normative change in the Temporal spec.
See: 514ede3
This commit is contained in:
parent
a73c71e877
commit
3ab1c52e2b
4 changed files with 443 additions and 29 deletions
|
@ -1079,60 +1079,83 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object,
|
|||
|
||||
// 1. Assert: Type(isoString) is String.
|
||||
|
||||
// 2. Let year, month, day, hour, minute, second, fraction, and calendar be the parts of isoString produced respectively by the DateYear, DateMonth, DateDay, TimeHour, TimeMinute, TimeSecond, TimeFraction, and CalendarName productions, or undefined if not present.
|
||||
// 2. Let year, month, day, fraction, and calendar be the parts of isoString produced respectively by the DateYear, DateMonth, DateDay, TimeFraction, and CalendarName productions, or undefined if not present.
|
||||
auto year_part = parse_result.date_year;
|
||||
auto month_part = parse_result.date_month;
|
||||
auto day_part = parse_result.date_day;
|
||||
auto hour_part = parse_result.time_hour;
|
||||
auto minute_part = parse_result.time_minute;
|
||||
auto second_part = parse_result.time_second;
|
||||
auto fraction_part = parse_result.time_fraction;
|
||||
auto calendar_part = parse_result.calendar_name;
|
||||
|
||||
// 3. If the first code unit of year is 0x2212 (MINUS SIGN), replace it with the code unit 0x002D (HYPHEN-MINUS).
|
||||
// 3. Let year be the part of isoString produced by the DateYear production.
|
||||
// NOTE: Duplicate assignment, already covered above (see https://github.com/tc39/proposal-temporal/pull/1987)
|
||||
|
||||
// 4. Let hour be the part of isoString produced by the TimeHour, TimeHourNotValidMonth, TimeHourNotThirtyOneDayMonth, or TimeHourTwoOnly productions, or undefined if none of those are present.
|
||||
auto hour_part = parse_result.time_hour;
|
||||
if (!hour_part.has_value())
|
||||
hour_part = parse_result.time_hour_not_valid_month;
|
||||
if (!hour_part.has_value())
|
||||
hour_part = parse_result.time_hour_not_thirty_one_day_month;
|
||||
if (!hour_part.has_value())
|
||||
hour_part = parse_result.time_hour_two_only;
|
||||
|
||||
// 5. Let minute be the part of isoString produced by the TimeMinute, TimeMinuteNotValidDay, TimeMinuteThirtyOnly, or TimeMinuteThirtyOneOnly productions, or undefined if none of those are present.
|
||||
auto minute_part = parse_result.time_minute;
|
||||
if (!minute_part.has_value())
|
||||
minute_part = parse_result.time_minute_not_valid_day;
|
||||
if (!minute_part.has_value())
|
||||
minute_part = parse_result.time_minute_thirty_only;
|
||||
if (!minute_part.has_value())
|
||||
minute_part = parse_result.time_minute_thirty_one_only;
|
||||
|
||||
// 6. Let second be the part of isoString produced by the TimeSecond or TimeSecondNotValidMonth productions, or undefined if neither of those are present.
|
||||
auto second_part = parse_result.time_second;
|
||||
if (!second_part.has_value())
|
||||
second_part = parse_result.time_second_not_valid_month;
|
||||
|
||||
// 7. If the first code unit of year is 0x2212 (MINUS SIGN), replace it with the code unit 0x002D (HYPHEN-MINUS).
|
||||
String normalized_year;
|
||||
if (year_part.has_value() && year_part->starts_with("\xE2\x88\x92"sv))
|
||||
normalized_year = String::formatted("-{}", year_part->substring_view(3));
|
||||
else
|
||||
normalized_year = year_part.value_or("0");
|
||||
|
||||
// 4. Set year to ! ToIntegerOrInfinity(year).
|
||||
// 8. Set year to ! ToIntegerOrInfinity(year).
|
||||
auto year = *normalized_year.to_int<i32>();
|
||||
|
||||
u8 month;
|
||||
// 5. If month is undefined, then
|
||||
// 9. If month is undefined, then
|
||||
if (!month_part.has_value()) {
|
||||
// a. Set month to 1.
|
||||
month = 1;
|
||||
}
|
||||
// 6. Else,
|
||||
// 10. Else,
|
||||
else {
|
||||
// a. Set month to ! ToIntegerOrInfinity(month).
|
||||
month = *month_part->to_uint<u8>();
|
||||
}
|
||||
|
||||
u8 day;
|
||||
// 7. If day is undefined, then
|
||||
// 11. If day is undefined, then
|
||||
if (!day_part.has_value()) {
|
||||
// a. Set day to 1.
|
||||
day = 1;
|
||||
}
|
||||
// 8. Else,
|
||||
// 12. Else,
|
||||
else {
|
||||
// a. Set day to ! ToIntegerOrInfinity(day).
|
||||
day = *day_part->to_uint<u8>();
|
||||
}
|
||||
|
||||
// 9. Set hour to ! ToIntegerOrInfinity(hour).
|
||||
// 13. Set hour to ! ToIntegerOrInfinity(hour).
|
||||
u8 hour = *hour_part.value_or("0"sv).to_uint<u8>();
|
||||
|
||||
// 10. Set minute to ! ToIntegerOrInfinity(minute).
|
||||
// 14. Set minute to ! ToIntegerOrInfinity(minute).
|
||||
u8 minute = *minute_part.value_or("0"sv).to_uint<u8>();
|
||||
|
||||
// 11. Set second to ! ToIntegerOrInfinity(second).
|
||||
// 15. Set second to ! ToIntegerOrInfinity(second).
|
||||
u8 second = *second_part.value_or("0"sv).to_uint<u8>();
|
||||
|
||||
// 12. If second is 60, then
|
||||
// 16. If second is 60, then
|
||||
if (second == 60) {
|
||||
// a. Set second to 59.
|
||||
second = 59;
|
||||
|
@ -1141,7 +1164,7 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object,
|
|||
u16 millisecond;
|
||||
u16 microsecond;
|
||||
u16 nanosecond;
|
||||
// 13. If fraction is not undefined, then
|
||||
// 17. If fraction is not undefined, then
|
||||
if (fraction_part.has_value()) {
|
||||
// a. Set fraction to the string-concatenation of the previous value of fraction and the string "000000000".
|
||||
auto fraction = String::formatted("{}000000000", *fraction_part);
|
||||
|
@ -1155,7 +1178,7 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object,
|
|||
// g. Set nanosecond to ! ToIntegerOrInfinity(nanosecond).
|
||||
nanosecond = *fraction.substring(7, 3).to_uint<u16>();
|
||||
}
|
||||
// 14. Else,
|
||||
// 18. Else,
|
||||
else {
|
||||
// a. Let millisecond be 0.
|
||||
millisecond = 0;
|
||||
|
@ -1165,15 +1188,15 @@ ThrowCompletionOr<ISODateTime> parse_iso_date_time(GlobalObject& global_object,
|
|||
nanosecond = 0;
|
||||
}
|
||||
|
||||
// 15. If ! IsValidISODate(year, month, day) is false, throw a RangeError exception.
|
||||
// 19. If ! IsValidISODate(year, month, day) is false, throw a RangeError exception.
|
||||
if (!is_valid_iso_date(year, month, day))
|
||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidISODate);
|
||||
|
||||
// 16. If ! IsValidTime(hour, minute, second, millisecond, microsecond, nanosecond) is false, throw a RangeError exception.
|
||||
// 20. If ! IsValidTime(hour, minute, second, millisecond, microsecond, nanosecond) is false, throw a RangeError exception.
|
||||
if (!is_valid_time(hour, minute, second, millisecond, microsecond, nanosecond))
|
||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidTime);
|
||||
|
||||
// 17. Return the Record { [[Year]]: year, [[Month]]: month, [[Day]]: day, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond, [[Calendar]]: calendar }.
|
||||
// 21. Return the Record { [[Year]]: year, [[Month]]: month, [[Day]]: day, [[Hour]]: hour, [[Minute]]: minute, [[Second]]: second, [[Millisecond]]: millisecond, [[Microsecond]]: microsecond, [[Nanosecond]]: nanosecond, [[Calendar]]: calendar }.
|
||||
return ISODateTime { .year = year, .month = month, .day = day, .hour = hour, .minute = minute, .second = second, .millisecond = millisecond, .microsecond = microsecond, .nanosecond = nanosecond, .calendar = calendar_part.has_value() ? *calendar_part : Optional<String>() };
|
||||
}
|
||||
|
||||
|
@ -1567,7 +1590,11 @@ ThrowCompletionOr<TemporalTime> parse_temporal_time_string(GlobalObject& global_
|
|||
// 4. Let result be ? ParseISODateTime(isoString).
|
||||
auto result = TRY(parse_iso_date_time(global_object, *parse_result));
|
||||
|
||||
// 5. Return the Record { [[Hour]]: result.[[Hour]], [[Minute]]: result.[[Minute]], [[Second]]: result.[[Second]], [[Millisecond]]: result.[[Millisecond]], [[Microsecond]]: result.[[Microsecond]], [[Nanosecond]]: result.[[Nanosecond]], [[Calendar]]: result.[[Calendar]] }.
|
||||
// 5. Assert: ParseText(! StringToCodePoints(isoString), CalendarDate) is a List of errors.
|
||||
// 6. Assert: ParseText(! StringToCodePoints(isoString), DateSpecYearMonth) is a List of errors.
|
||||
// 7. Assert: ParseText(! StringToCodePoints(isoString), DateSpecMonthDay) is a List of errors.
|
||||
|
||||
// 8. Return the Record { [[Hour]]: result.[[Hour]], [[Minute]]: result.[[Minute]], [[Second]]: result.[[Second]], [[Millisecond]]: result.[[Millisecond]], [[Microsecond]]: result.[[Microsecond]], [[Nanosecond]]: result.[[Nanosecond]], [[Calendar]]: result.[[Calendar]] }.
|
||||
return TemporalTime { .hour = result.hour, .minute = result.minute, .second = result.second, .millisecond = result.millisecond, .microsecond = result.microsecond, .nanosecond = result.nanosecond, .calendar = move(result.calendar) };
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue