diff options
author | Linus Groh <mail@linusgroh.de> | 2021-07-25 20:19:37 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-07-25 23:44:36 +0100 |
commit | 96e63415b6aee4fb138a1b6b3ba819aec2466f93 (patch) | |
tree | e6f8c6169d9c120d74aa1fffef4c41bfdcccf3ac /Userland | |
parent | d428787e18f4621871adb90c22358c675349eda8 (diff) | |
download | serenity-96e63415b6aee4fb138a1b6b3ba819aec2466f93.zip |
LibJS: Implement Temporal.TimeZone.prototype.getOffsetNanosecondsFor()
Diffstat (limited to 'Userland')
6 files changed, 61 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 798b9f67c3..63f95930ff 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -182,6 +182,7 @@ namespace JS { P(getMilliseconds) \ P(getMinutes) \ P(getMonth) \ + P(getOffsetNanosecondsFor) \ P(getOwnPropertyDescriptor) \ P(getOwnPropertyDescriptors) \ P(getOwnPropertyNames) \ diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index 6e19933543..2240f103e9 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -92,6 +92,15 @@ TimeZone* create_temporal_time_zone(GlobalObject& global_object, String const& i return object; } +// 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) +{ + // 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; +} + // https://tc39.es/proposal-temporal/#prod-TimeZoneNumericUTCOffset static bool parse_time_zone_numeric_utc_offset_syntax(String const& offset_string, StringView& sign, StringView& hours, Optional<StringView>& minutes, Optional<StringView>& seconds, Optional<StringView>& fraction) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h index 20dfd22233..adf94b8f14 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h @@ -39,6 +39,7 @@ bool is_valid_time_zone_name(String const& time_zone); String canonicalize_time_zone_name(String const& time_zone); String default_time_zone(); TimeZone* create_temporal_time_zone(GlobalObject&, String const& identifier, FunctionObject* new_target = nullptr); +i64 get_iana_time_zone_offset_nanoseconds(BigInt const& epoch_nanoseconds, String const& time_zone_identifier); double parse_time_zone_offset_string(GlobalObject&, String const&); String format_time_zone_offset_string(double offset_nanoseconds); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp index bbaf036d96..f036e25064 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp @@ -5,6 +5,7 @@ */ #include <LibJS/Runtime/GlobalObject.h> +#include <LibJS/Runtime/Temporal/Instant.h> #include <LibJS/Runtime/Temporal/TimeZone.h> #include <LibJS/Runtime/Temporal/TimeZonePrototype.h> @@ -24,6 +25,7 @@ void TimeZonePrototype::initialize(GlobalObject& global_object) u8 attr = Attribute::Writable | Attribute::Configurable; define_native_accessor(vm.names.id, id_getter, {}, Attribute::Configurable); + define_native_function(vm.names.getOffsetNanosecondsFor, get_offset_nanoseconds_for, 1, attr); define_native_function(vm.names.toString, to_string, 0, attr); define_native_function(vm.names.toJSON, to_json, 0, attr); @@ -54,6 +56,28 @@ JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::id_getter) return js_string(vm, time_zone.to_string(global_object)); } +// 11.4.4 Temporal.TimeZone.prototype.getOffsetNanosecondsFor ( instant ), https://tc39.es/proposal-temporal/#sec-temporal.timezone.prototype.getoffsetnanosecondsfor +JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::get_offset_nanoseconds_for) +{ + // 1. Let timeZone be the this value. + // 2. Perform ? RequireInternalSlot(timeZone, [[InitializedTemporalTimeZone]]). + auto* time_zone = typed_this(global_object); + if (vm.exception()) + return {}; + + // 3. Set instant to ? ToTemporalInstant(instant). + auto* instant = to_temporal_instant(global_object, vm.argument(0)); + if (vm.exception()) + return {}; + + // 4. If timeZone.[[OffsetNanoseconds]] is not undefined, return timeZone.[[OffsetNanoseconds]]. + if (time_zone->offset_nanoseconds().has_value()) + return Value(*time_zone->offset_nanoseconds()); + + // 5. Return ! GetIANATimeZoneOffsetNanoseconds(instant.[[Nanoseconds]], timeZone.[[Identifier]]). + return Value((double)get_iana_time_zone_offset_nanoseconds(instant->nanoseconds(), time_zone->identifier())); +} + // 11.4.11 Temporal.TimeZone.prototype.toString ( ), https://tc39.es/proposal-temporal/#sec-temporal.timezone.prototype.tostring JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::to_string) { diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.h b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.h index 1eceb15186..e69c5751cc 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.h @@ -20,6 +20,7 @@ public: private: JS_DECLARE_NATIVE_FUNCTION(id_getter); + JS_DECLARE_NATIVE_FUNCTION(get_offset_nanoseconds_for); JS_DECLARE_NATIVE_FUNCTION(to_string); JS_DECLARE_NATIVE_FUNCTION(to_json); }; diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.prototype.getOffsetNanosecondsFor.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.prototype.getOffsetNanosecondsFor.js new file mode 100644 index 0000000000..913b5c3ccd --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.prototype.getOffsetNanosecondsFor.js @@ -0,0 +1,25 @@ +describe("correct behavior", () => { + test("length is 1", () => { + expect(Temporal.TimeZone.prototype.getOffsetNanosecondsFor).toHaveLength(1); + }); + + test("basic functionality", () => { + const timeZone = new Temporal.TimeZone("UTC"); + const instant = new Temporal.Instant(0n); + expect(timeZone.getOffsetNanosecondsFor(instant)).toBe(0); + }); + + test("custom offset", () => { + const timeZone = new Temporal.TimeZone("+01:30"); + const instant = new Temporal.Instant(0n); + expect(timeZone.getOffsetNanosecondsFor(instant)).toBe(5400000000000); + }); +}); + +test("errors", () => { + test("this value must be a Temporal.TimeZone object", () => { + expect(() => { + Temporal.TimeZone.prototype.getOffsetNanosecondsFor.call("foo"); + }).toThrowWithMessage(TypeError, "Not a Temporal.TimeZone"); + }); +}); |