Duration.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
  4. * Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #pragma once
  9. #include <AK/Optional.h>
  10. #include <LibCrypto/BigFraction/BigFraction.h>
  11. #include <LibJS/Runtime/Completion.h>
  12. #include <LibJS/Runtime/Object.h>
  13. #include <LibJS/Runtime/Temporal/AbstractOperations.h>
  14. #include <LibJS/Runtime/Temporal/ISORecords.h>
  15. #include <LibJS/Runtime/Value.h>
  16. namespace JS::Temporal {
  17. #define JS_ENUMERATE_DURATION_UNITS \
  18. __JS_ENUMERATE(years) \
  19. __JS_ENUMERATE(months) \
  20. __JS_ENUMERATE(weeks) \
  21. __JS_ENUMERATE(days) \
  22. __JS_ENUMERATE(hours) \
  23. __JS_ENUMERATE(minutes) \
  24. __JS_ENUMERATE(seconds) \
  25. __JS_ENUMERATE(milliseconds) \
  26. __JS_ENUMERATE(microseconds) \
  27. __JS_ENUMERATE(nanoseconds)
  28. class Duration final : public Object {
  29. JS_OBJECT(Duration, Object);
  30. GC_DECLARE_ALLOCATOR(Duration);
  31. public:
  32. virtual ~Duration() override = default;
  33. #define __JS_ENUMERATE(unit) \
  34. [[nodiscard]] double unit() const { return m_##unit; }
  35. JS_ENUMERATE_DURATION_UNITS
  36. #undef __JS_ENUMERATE
  37. private:
  38. Duration(double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Object& prototype);
  39. double m_years { 0 }; // [[Years]]
  40. double m_months { 0 }; // [[Months]]
  41. double m_weeks { 0 }; // [[Weeks]]
  42. double m_days { 0 }; // [[Days]]
  43. double m_hours { 0 }; // [[Hours]]
  44. double m_minutes { 0 }; // [[Minutes]]
  45. double m_seconds { 0 }; // [[Seconds]]
  46. double m_milliseconds { 0 }; // [[Milliseconds]]
  47. double m_microseconds { 0 }; // [[Microseconds]]
  48. double m_nanoseconds { 0 }; // [[Nanoseconds]]
  49. };
  50. // 7.5.1 Date Duration Records, https://tc39.es/proposal-temporal/#sec-temporal-date-duration-records
  51. struct DateDuration {
  52. double years { 0 };
  53. double months { 0 };
  54. double weeks { 0 };
  55. double days { 0 };
  56. };
  57. // 7.5.2 Partial Duration Records, https://tc39.es/proposal-temporal/#sec-temporal-partial-duration-records
  58. struct PartialDuration {
  59. static PartialDuration zero()
  60. {
  61. return { .years = 0, .months = 0, .weeks = 0, .days = 0, .hours = 0, .minutes = 0, .seconds = 0, .milliseconds = 0, .microseconds = 0, .nanoseconds = 0 };
  62. }
  63. bool any_field_defined() const
  64. {
  65. return years.has_value() || months.has_value() || weeks.has_value() || days.has_value() || hours.has_value() || minutes.has_value() || seconds.has_value() || milliseconds.has_value() || microseconds.has_value() || nanoseconds.has_value();
  66. }
  67. Optional<double> years;
  68. Optional<double> months;
  69. Optional<double> weeks;
  70. Optional<double> days;
  71. Optional<double> hours;
  72. Optional<double> minutes;
  73. Optional<double> seconds;
  74. Optional<double> milliseconds;
  75. Optional<double> microseconds;
  76. Optional<double> nanoseconds;
  77. };
  78. extern TimeDuration const MAX_TIME_DURATION;
  79. // 7.5.3 Internal Duration Records, https://tc39.es/proposal-temporal/#sec-temporal-internal-duration-records
  80. struct InternalDuration {
  81. DateDuration date;
  82. TimeDuration time;
  83. };
  84. // 7.5.32 Duration Nudge Result Records, https://tc39.es/proposal-temporal/#sec-temporal-duration-nudge-result-records
  85. struct DurationNudgeResult {
  86. InternalDuration duration;
  87. TimeDuration nudged_epoch_ns;
  88. bool did_expand_calendar_unit { false };
  89. };
  90. struct CalendarNudgeResult {
  91. DurationNudgeResult nudge_result;
  92. Crypto::BigFraction total;
  93. };
  94. DateDuration zero_date_duration(VM&);
  95. InternalDuration to_internal_duration_record(VM&, Duration const&);
  96. InternalDuration to_internal_duration_record_with_24_hour_days(VM&, Duration const&);
  97. ThrowCompletionOr<DateDuration> to_date_duration_record_without_time(VM&, Duration const&);
  98. ThrowCompletionOr<GC::Ref<Duration>> temporal_duration_from_internal(VM&, InternalDuration const&, Unit largest_unit);
  99. ThrowCompletionOr<DateDuration> create_date_duration_record(VM&, double years, double months, double weeks, double days);
  100. ThrowCompletionOr<DateDuration> adjust_date_duration_record(VM&, DateDuration const&, double days, Optional<double> weeks = {}, Optional<double> months = {});
  101. ThrowCompletionOr<InternalDuration> combine_date_and_time_duration(VM&, DateDuration, TimeDuration);
  102. ThrowCompletionOr<GC::Ref<Duration>> to_temporal_duration(VM&, Value);
  103. i8 duration_sign(Duration const&);
  104. i8 date_duration_sign(DateDuration const&);
  105. i8 internal_duration_sign(InternalDuration const&);
  106. bool is_valid_duration(double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds);
  107. Unit default_temporal_largest_unit(Duration const&);
  108. ThrowCompletionOr<PartialDuration> to_temporal_partial_duration_record(VM&, Value temporal_duration_like);
  109. ThrowCompletionOr<GC::Ref<Duration>> create_temporal_duration(VM&, double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, GC::Ptr<FunctionObject> new_target = {});
  110. GC::Ref<Duration> create_negated_temporal_duration(VM&, Duration const&);
  111. TimeDuration time_duration_from_components(double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds);
  112. ThrowCompletionOr<TimeDuration> add_time_duration(VM&, TimeDuration const&, TimeDuration const&);
  113. ThrowCompletionOr<TimeDuration> add_24_hour_days_to_time_duration(VM&, TimeDuration const&, double days);
  114. TimeDuration add_time_duration_to_epoch_nanoseconds(TimeDuration const& duration, TimeDuration const& epoch_nanoseconds);
  115. i8 compare_time_duration(TimeDuration const&, TimeDuration const&);
  116. TimeDuration time_duration_from_epoch_nanoseconds_difference(TimeDuration const&, TimeDuration const&);
  117. ThrowCompletionOr<TimeDuration> round_time_duration_to_increment(VM&, TimeDuration const&, Crypto::UnsignedBigInteger const& increment, RoundingMode);
  118. i8 time_duration_sign(TimeDuration const&);
  119. ThrowCompletionOr<TimeDuration> round_time_duration(VM&, TimeDuration const&, Crypto::UnsignedBigInteger const& increment, Unit, RoundingMode);
  120. ThrowCompletionOr<CalendarNudgeResult> nudge_to_calendar_unit(VM&, i8 sign, InternalDuration const&, TimeDuration const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
  121. ThrowCompletionOr<DurationNudgeResult> nudge_to_zoned_time(VM&, i8 sign, InternalDuration const&, ISODateTime const&, StringView time_zone, StringView calendar, u64 increment, Unit, RoundingMode);
  122. ThrowCompletionOr<DurationNudgeResult> nudge_to_day_or_time(VM&, InternalDuration const&, TimeDuration const& dest_epoch_ns, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode);
  123. ThrowCompletionOr<InternalDuration> bubble_relative_duration(VM&, i8 sign, InternalDuration, TimeDuration const& nudged_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, Unit smallest_unit);
  124. ThrowCompletionOr<InternalDuration> round_relative_duration(VM&, InternalDuration, TimeDuration const& dest_epoch_ns, ISODateTime const&, Optional<StringView> time_zone, StringView calendar, Unit largest_unit, u64 increment, Unit smallest_unit, RoundingMode);
  125. double total_time_duration(TimeDuration const&, Unit);
  126. String temporal_duration_to_string(Duration const&, Precision);
  127. ThrowCompletionOr<GC::Ref<Duration>> add_durations(VM&, ArithmeticOperation, Duration const&, Value);
  128. }