LibJS: Implement stringification Temporal.PlainTime prototypes

This commit is contained in:
Timothy Flynn 2024-11-23 11:10:35 -05:00 committed by Tim Flynn
commit ab3c825fa8
Notes: github-actions[bot] 2024-11-24 00:37:56 +00:00
7 changed files with 270 additions and 0 deletions

View file

@ -441,6 +441,16 @@ ThrowCompletionOr<TemporalTimeLike> to_temporal_time_record(VM& vm, Object const
return result;
}
// 4.5.13 TimeRecordToString ( time, precision ), https://tc39.es/proposal-temporal/#sec-temporal-timerecordtostring
String time_record_to_string(Time const& time, SecondsStringPrecision::Precision precision)
{
// 1. Let subSecondNanoseconds be time.[[Millisecond]] × 10**6 + time.[[Microsecond]] × 10**3 + time.[[Nanosecond]].
auto sub_second_nanoseconds = (static_cast<u64>(time.millisecond) * 1'000'000) + (static_cast<u64>(time.microsecond) * 1000) + static_cast<u64>(time.nanosecond);
// 2. Return FormatTimeString(time.[[Hour]], time.[[Minute]], time.[[Second]], subSecondNanoseconds, precision).
return format_time_string(time.hour, time.minute, time.second, sub_second_nanoseconds, precision);
}
// 4.5.14 CompareTimeRecord ( time1, time2 ), https://tc39.es/proposal-temporal/#sec-temporal-comparetimerecord
i8 compare_time_record(Time const& time1, Time const& time2)
{
@ -499,4 +509,101 @@ Time add_time(Time const& time, TimeDuration const& time_duration)
return balance_time(time.hour, time.minute, time.second, time.millisecond, time.microsecond, nanoseconds);
}
// 4.5.16 RoundTime ( time, increment, unit, roundingMode ), https://tc39.es/proposal-temporal/#sec-temporal-roundtime
Time round_time(Time const& time, u64 increment, Unit unit, RoundingMode rounding_mode)
{
double quantity = 0;
switch (unit) {
// 1. If unit is DAY or HOUR, then
case Unit::Day:
case Unit::Hour:
// a. Let quantity be ((((time.[[Hour]] × 60 + time.[[Minute]]) × 60 + time.[[Second]]) × 1000 + time.[[Millisecond]]) × 1000 + time.[[Microsecond]]) × 1000 + time.[[Nanosecond]].
quantity = ((((time.hour * 60.0 + time.minute) * 60.0 + time.second) * 1000.0 + time.millisecond) * 1000.0 + time.microsecond) * 1000.0 + time.nanosecond;
break;
// 2. Else if unit is MINUTE, then
case Unit::Minute:
// a. Let quantity be (((time.[[Minute]] × 60 + time.[[Second]]) × 1000 + time.[[Millisecond]]) × 1000 + time.[[Microsecond]]) × 1000 + time.[[Nanosecond]].
quantity = (((time.minute * 60.0 + time.second) * 1000.0 + time.millisecond) * 1000.0 + time.microsecond) * 1000.0 + time.nanosecond;
break;
// 3. Else if unit is SECOND, then
case Unit::Second:
// a. Let quantity be ((time.[[Second]] × 1000 + time.[[Millisecond]]) × 1000 + time.[[Microsecond]]) × 1000 + time.[[Nanosecond]].
quantity = ((time.second * 1000.0 + time.millisecond) * 1000.0 + time.microsecond) * 1000.0 + time.nanosecond;
break;
// 4. Else if unit is MILLISECOND, then
case Unit::Millisecond:
// a. Let quantity be (time.[[Millisecond]] × 1000 + time.[[Microsecond]]) × 1000 + time.[[Nanosecond]].
quantity = (time.millisecond * 1000.0 + time.microsecond) * 1000.0 + time.nanosecond;
break;
// 5. Else if unit is MICROSECOND, then
case Unit::Microsecond:
// a. Let quantity be time.[[Microsecond]] × 1000 + time.[[Nanosecond]].
quantity = time.microsecond * 1000.0 + time.nanosecond;
break;
// 6. Else,
case Unit::Nanosecond:
// a. Assert: unit is NANOSECOND.
// b. Let quantity be time.[[Nanosecond]].
quantity = time.nanosecond;
break;
default:
VERIFY_NOT_REACHED();
}
// 7. Let unitLength be the value in the "Length in Nanoseconds" column of the row of Table 21 whose "Value" column contains unit.
auto unit_length = temporal_unit_length_in_nanoseconds(unit).to_u64();
// 8. Let result be RoundNumberToIncrement(quantity, increment × unitLength, roundingMode) / unitLength.
auto result = round_number_to_increment(quantity, increment * unit_length, rounding_mode) / static_cast<double>(unit_length);
switch (unit) {
// 9. If unit is DAY, then
case Unit::Day:
// a. Return CreateTimeRecord(0, 0, 0, 0, 0, 0, result).
return create_time_record(0, 0, 0, 0, 0, 0, result);
// 10. If unit is HOUR, then
case Unit::Hour:
// a. Return BalanceTime(result, 0, 0, 0, 0, 0).
return balance_time(result, 0, 0, 0, 0, 0);
// 11. If unit is MINUTE, then
case Unit::Minute:
// a. Return BalanceTime(time.[[Hour]], result, 0, 0, 0, 0).
return balance_time(time.hour, result, 0, 0, 0, 0);
// 12. If unit is SECOND, then
case Unit::Second:
// a. Return BalanceTime(time.[[Hour]], time.[[Minute]], result, 0, 0, 0).
return balance_time(time.hour, time.minute, result, 0, 0, 0);
// 13. If unit is MILLISECOND, then
case Unit::Millisecond:
// a. Return BalanceTime(time.[[Hour]], time.[[Minute]], time.[[Second]], result, 0, 0).
return balance_time(time.hour, time.minute, time.second, result, 0, 0);
// 14. If unit is MICROSECOND, then
case Unit::Microsecond:
// a. Return BalanceTime(time.[[Hour]], time.[[Minute]], time.[[Second]], time.[[Millisecond]], result, 0).
return balance_time(time.hour, time.minute, time.second, time.millisecond, result, 0);
// 15. Assert: unit is NANOSECOND.
case Unit::Nanosecond:
// 16. Return BalanceTime(time.[[Hour]], time.[[Minute]], time.[[Second]], time.[[Millisecond]], time.[[Microsecond]], result).
return balance_time(time.hour, time.minute, time.second, time.millisecond, time.microsecond, result);
default:
break;
}
VERIFY_NOT_REACHED();
}
}