Bladeren bron

LibJS: Implement Date.UTC()

Nico Weber 4 jaren geleden
bovenliggende
commit
1eac1b360b

+ 20 - 0
Libraries/LibJS/Runtime/DateConstructor.cpp

@@ -46,6 +46,7 @@ void DateConstructor::initialize(GlobalObject& global_object)
     define_property("length", Value(7), Attribute::Configurable);
 
     define_native_function("now", now, 0, Attribute::Writable | Attribute::Configurable);
+    define_native_function("UTC", utc, 1, Attribute::Writable | Attribute::Configurable);
 }
 
 DateConstructor::~DateConstructor()
@@ -112,4 +113,23 @@ JS_DEFINE_NATIVE_FUNCTION(DateConstructor::now)
     return Value(tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
 }
 
+JS_DEFINE_NATIVE_FUNCTION(DateConstructor::utc)
+{
+    auto arg_or = [&interpreter](size_t i, i32 fallback) { return interpreter.argument_count() > i ? interpreter.argument(i).to_i32(interpreter) : fallback; };
+    int year = interpreter.argument(0).to_i32(interpreter);
+    if (year >= 0 && year <= 99)
+      year += 1900;
+
+    struct tm tm = {};
+    tm.tm_year = year - 1900;
+    tm.tm_mon = arg_or(1, 0); // 0-based in both tm and JavaScript
+    tm.tm_mday = arg_or(2, 1);
+    tm.tm_hour = arg_or(3, 0);
+    tm.tm_min = arg_or(4, 0);
+    tm.tm_sec = arg_or(5, 0);
+    // timegm() doesn't read tm.tm_wday and tm.tm_yday, no need to fill them in.
+
+    int milliseconds = arg_or(6, 0);
+    return Value(1000.0 * timegm(&tm) + milliseconds);
+}
 }

+ 1 - 0
Libraries/LibJS/Runtime/DateConstructor.h

@@ -45,6 +45,7 @@ private:
     virtual bool has_constructor() const override { return true; }
 
     JS_DECLARE_NATIVE_FUNCTION(now);
+    JS_DECLARE_NATIVE_FUNCTION(utc);
 };
 
 }

+ 10 - 0
Libraries/LibJS/Tests/builtins/Date/Date.UTC.js

@@ -0,0 +1,10 @@
+test("basic functionality", () => {
+    // FIXME: Years before 1970 don't work. Once they do, add a test. Also add a test with a year before 1900 then.
+    expect(Date.UTC(2020)).toBe(1577836800000);
+    expect(Date.UTC(2000, 10)).toBe(973036800000);
+    expect(Date.UTC(1980, 5, 30)).toBe(331171200000);
+    expect(Date.UTC(1980, 5, 30, 13)).toBe(331218000000);
+    expect(Date.UTC(1970, 5, 30, 13, 30)).toBe(15600600000);
+    expect(Date.UTC(1970, 0, 1, 0, 0, 59)).toBe(59000);
+    expect(Date.UTC(1970, 0, 1, 0, 0, 0, 999)).toBe(999);
+});