LibJS: Implement Date.prototype.toISOString()

This commit is contained in:
Nico Weber 2020-08-20 16:29:27 -04:00 committed by Andreas Kling
parent 1eac1b360b
commit a6b68451dc
Notes: sideshowbarker 2024-07-19 03:22:38 +09:00
5 changed files with 55 additions and 0 deletions

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AK/StringBuilder.h>
#include <LibCore/DateTime.h>
#include <LibJS/Heap/Heap.h>
#include <LibJS/Interpreter.h>
@ -48,4 +49,36 @@ Date::~Date()
{
}
String Date::iso_date_string() const
{
time_t timestamp = m_datetime.timestamp();
struct tm tm;
gmtime_r(&timestamp, &tm);
int year = tm.tm_year + 1900;
int month = tm.tm_mon + 1;
StringBuilder builder;
if (year < 0)
builder.appendf("-%06d", -year);
else if (year > 9999)
builder.appendf("+%06d", year);
else
builder.appendf("%04d", year);
builder.append('-');
builder.appendf("%02d", month);
builder.append('-');
builder.appendf("%02d", tm.tm_mday);
builder.append('T');
builder.appendf("%02d", tm.tm_hour);
builder.append(':');
builder.appendf("%02d", tm.tm_min);
builder.append(':');
builder.appendf("%02d", tm.tm_sec);
builder.append('.');
builder.appendf("%03d", m_milliseconds);
builder.append('Z');
return builder.build();
}
}

View file

@ -52,6 +52,8 @@ public:
return String::format("%s %s", date_string().characters(), time_string().characters());
}
String iso_date_string() const;
// FIXME: One day, implement real locale support. Until then, everyone gets what the Clock MenuApplet displays.
String locale_date_string() const { return m_datetime.to_string("%Y-%m-%d"); }
String locale_string() const { return m_datetime.to_string(); }

View file

@ -67,6 +67,7 @@ void DatePrototype::initialize(GlobalObject& global_object)
define_native_function("getSeconds", get_seconds, 0, attr);
define_native_function("getTime", get_time, 0, attr);
define_native_function("toDateString", to_date_string, 0, attr);
define_native_function("toISOString", to_iso_string, 0, attr);
define_native_function("toLocaleDateString", to_locale_date_string, 0, attr);
define_native_function("toLocaleString", to_locale_string, 0, attr);
define_native_function("toLocaleTimeString", to_locale_time_string, 0, attr);
@ -169,6 +170,15 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_date_string)
return js_string(interpreter, move(string));
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_iso_string)
{
auto* this_object = typed_this(interpreter, global_object);
if (!this_object)
return {};
auto string = this_object->iso_date_string();
return js_string(interpreter, move(string));
}
JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_locale_date_string)
{
auto* this_object = typed_this(interpreter, global_object);

View file

@ -48,6 +48,7 @@ private:
JS_DECLARE_NATIVE_FUNCTION(get_seconds);
JS_DECLARE_NATIVE_FUNCTION(get_time);
JS_DECLARE_NATIVE_FUNCTION(to_date_string);
JS_DECLARE_NATIVE_FUNCTION(to_iso_string);
JS_DECLARE_NATIVE_FUNCTION(to_locale_date_string);
JS_DECLARE_NATIVE_FUNCTION(to_locale_string);
JS_DECLARE_NATIVE_FUNCTION(to_locale_time_string);

View file

@ -0,0 +1,9 @@
test("basic functionality", () => {
expect(new Date(1597955034555).toISOString()).toBe("2020-08-20T20:23:54.555Z");
// FIXME: Add these once they work.
//expect(new Date(Date.UTC(22020)).toISOString()).toBe("+022020-01-01T00:00:00.000Z");
//expect(new Date(Date.UTC(1950)).toISOString()).toBe("1950-01-01T00:00:00.000Z");
//expect(new Date(Date.UTC(1800)).toISOString()).toBe("1800-01-01T00:00:00.000Z");
//expect(new Date(Date.UTC(-100)).toISOString()).toBe("-000100-01-01T00:00:00.000Z");
});