summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2021-07-25 20:19:37 +0100
committerLinus Groh <mail@linusgroh.de>2021-07-25 23:44:36 +0100
commit96e63415b6aee4fb138a1b6b3ba819aec2466f93 (patch)
treee6f8c6169d9c120d74aa1fffef4c41bfdcccf3ac /Userland
parentd428787e18f4621871adb90c22358c675349eda8 (diff)
downloadserenity-96e63415b6aee4fb138a1b6b3ba819aec2466f93.zip
LibJS: Implement Temporal.TimeZone.prototype.getOffsetNanosecondsFor()
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp9
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp24
-rw-r--r--Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.h1
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.prototype.getOffsetNanosecondsFor.js25
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");
+ });
+});