mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:17:35 +00:00
LibJS: Actually implement get_iana_time_zone_offset_nanoseconds()
Instead of hard-coding an UTC offset of zero seconds, which worked for the sole UTC time zone, we can now get the proper offset from the TZDB!
This commit is contained in:
parent
d527eb62da
commit
355fbcb702
3 changed files with 79 additions and 15 deletions
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/DateTimeLexer.h>
|
||||
#include <AK/Time.h>
|
||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
|
@ -170,12 +171,34 @@ MarkedValueList get_iana_time_zone_epoch_value(GlobalObject& global_object, [[ma
|
|||
}
|
||||
|
||||
// 11.6.5 GetIANATimeZoneOffsetNanoseconds ( epochNanoseconds, timeZoneIdentifier ), https://tc39.es/proposal-temporal/#sec-temporal-getianatimezoneoffsetnanoseconds
|
||||
i64 get_iana_time_zone_offset_nanoseconds([[maybe_unused]] BigInt const& epoch_nanoseconds, [[maybe_unused]] String const& time_zone_identifier)
|
||||
i64 get_iana_time_zone_offset_nanoseconds(BigInt const& epoch_nanoseconds, String const& time_zone_identifier)
|
||||
{
|
||||
// The abstract operation GetIANATimeZoneOffsetNanoseconds is an implementation-defined algorithm that returns an integer representing the offset of the IANA time zone identified by timeZoneIdentifier from UTC, at the instant corresponding to epochNanoseconds.
|
||||
// Given the same values of epochNanoseconds and timeZoneIdentifier, the result must be the same for the lifetime of the surrounding agent.
|
||||
// TODO: Implement this
|
||||
return 0;
|
||||
|
||||
// Only called with validated TimeZone [[Identifier]] as argument.
|
||||
auto time_zone = ::TimeZone::time_zone_from_string(time_zone_identifier);
|
||||
VERIFY(time_zone.has_value());
|
||||
|
||||
// Since Time::from_seconds() and Time::from_nanoseconds() both take an i64, converting to
|
||||
// seconds first gives us a greater range. The TZDB doesn't have sub-second offsets.
|
||||
auto seconds = epoch_nanoseconds.big_integer().divided_by("1000000000"_bigint).quotient;
|
||||
|
||||
// The provided epoch (nano)seconds value is potentially out of range for AK::Time and subsequently
|
||||
// get_time_zone_offset(). We can safely assume that the TZDB has no useful information that far
|
||||
// into the past and future anyway, so clamp it to the i64 range.
|
||||
Time time;
|
||||
if (seconds < Crypto::SignedBigInteger::create_from(NumericLimits<i64>::min()))
|
||||
time = Time::min();
|
||||
else if (seconds > Crypto::SignedBigInteger::create_from(NumericLimits<i64>::max()))
|
||||
time = Time::max();
|
||||
else
|
||||
time = Time::from_seconds(*seconds.to_base(10).to_int<i64>());
|
||||
|
||||
auto offset_seconds = ::TimeZone::get_time_zone_offset(*time_zone, time);
|
||||
VERIFY(offset_seconds.has_value());
|
||||
|
||||
return *offset_seconds * 1'000'000'000;
|
||||
}
|
||||
|
||||
// 11.6.6 GetIANATimeZoneNextTransition ( epochNanoseconds, timeZoneIdentifier ), https://tc39.es/proposal-temporal/#sec-temporal-getianatimezonenexttransition
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue