diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-01-05 12:26:15 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-01-05 20:05:12 +0100 |
commit | 7a0830bb24e1e2ec144558ae8529f34c1f9393ba (patch) | |
tree | d5624b853f2cdd75c4a1a20ccc8a6f156b78da6d | |
parent | e8f860048ebb3a480c9ec3b8899c3fb84e7226c9 (diff) | |
download | serenity-7a0830bb24e1e2ec144558ae8529f34c1f9393ba.zip |
LibJS: Use AK::Time to implement the MakeDay AO
We currently use Core::DateTime create, which internally uses mktime().
This has the issues pointed out by the (now removed) FIXME, but also has
an issue on macOS where years before 1900 are not supported.
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Date.cpp | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Date.cpp b/Userland/Libraries/LibJS/Runtime/Date.cpp index f68f27f307..4eb86742d8 100644 --- a/Userland/Libraries/LibJS/Runtime/Date.cpp +++ b/Userland/Libraries/LibJS/Runtime/Date.cpp @@ -5,6 +5,7 @@ */ #include <AK/StringBuilder.h> +#include <AK/Time.h> #include <LibCore/DateTime.h> #include <LibJS/Runtime/AbstractOperations.h> #include <LibJS/Runtime/Date.h> @@ -356,24 +357,18 @@ Value make_day(GlobalObject& global_object, Value year, Value month, Value date) // 4. Let dt be 𝔽(! ToIntegerOrInfinity(date)). auto dt = MUST(date.to_integer_or_infinity(global_object)); // 5. Let ym be y + 𝔽(floor(ℝ(m) / 12)). - auto ym = Value(y + floor(m / 12)); + auto ym = y + floor(m / 12); // 6. If ym is not finite, return NaN. - if (!ym.is_finite_number()) + if (!Value(ym).is_finite_number()) return js_nan(); // 7. Let mn be 𝔽(ℝ(m) modulo 12). - // NOTE: This calculation has no side-effects and is unused, so we omit it + auto mn = modulo(m, 12); // 8. Find a finite time value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn and DateFromTime(t) is 1𝔽; but if this is not possible (because some argument is out of range), return NaN. - if (!AK::is_within_range<int>(y) || !AK::is_within_range<int>(m + 1)) + if (!AK::is_within_range<int>(ym) || !AK::is_within_range<int>(mn + 1)) return js_nan(); - // FIXME: Core::DateTime assumes the argument values are in local time, which is not the case here. - // Let mktime() think local time is UTC by temporarily overwriting the TZ environment variable, - // so that the values are not adjusted. Core::DateTime should probably learn to deal with both - // local time and UTC time itself. - auto* tz = getenv("TZ"); - VERIFY(setenv("TZ", "UTC", 1) == 0); - auto t = Core::DateTime::create(static_cast<int>(y), static_cast<int>(m + 1), 1).timestamp() * 1000; - tz ? setenv("TZ", tz, 1) : unsetenv("TZ"); + auto t = days_since_epoch(static_cast<int>(ym), static_cast<int>(mn) + 1, 1) * MS_PER_DAY; + // 9. Return Day(t) + dt - 1𝔽. return Value(day(static_cast<double>(t)) + dt - 1); } |