Now.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibJS/Runtime/Date.h>
  8. #include <LibJS/Runtime/Temporal/Instant.h>
  9. #include <LibJS/Runtime/Temporal/Now.h>
  10. #include <LibJS/Runtime/Temporal/PlainDate.h>
  11. #include <LibJS/Runtime/Temporal/PlainDateTime.h>
  12. #include <LibJS/Runtime/Temporal/PlainTime.h>
  13. #include <LibJS/Runtime/Temporal/TimeZone.h>
  14. namespace JS::Temporal {
  15. GC_DEFINE_ALLOCATOR(Now);
  16. // 2 The Temporal.Now Object, https://tc39.es/proposal-temporal/#sec-temporal-now-object
  17. Now::Now(Realm& realm)
  18. : Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype())
  19. {
  20. }
  21. void Now::initialize(Realm& realm)
  22. {
  23. Base::initialize(realm);
  24. auto& vm = this->vm();
  25. // 2.1.1 Temporal.Now [ %Symbol.toStringTag% ], https://tc39.es/proposal-temporal/#sec-temporal-now-%symbol.tostringtag%
  26. define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Temporal.Now"_string), Attribute::Configurable);
  27. u8 attr = Attribute::Writable | Attribute::Configurable;
  28. define_native_function(realm, vm.names.timeZoneId, time_zone_id, 0, attr);
  29. define_native_function(realm, vm.names.instant, instant, 0, attr);
  30. define_native_function(realm, vm.names.plainDateTimeISO, plain_date_time_iso, 0, attr);
  31. define_native_function(realm, vm.names.plainDateISO, plain_date_iso, 0, attr);
  32. define_native_function(realm, vm.names.plainTimeISO, plain_time_iso, 0, attr);
  33. }
  34. // 2.2.1 Temporal.Now.timeZoneId ( ), https://tc39.es/proposal-temporal/#sec-temporal.now.timezoneid
  35. JS_DEFINE_NATIVE_FUNCTION(Now::time_zone_id)
  36. {
  37. // 1. Return SystemTimeZoneIdentifier().
  38. return PrimitiveString::create(vm, system_time_zone_identifier());
  39. }
  40. // 2.2.2 Temporal.Now.instant ( ), https://tc39.es/proposal-temporal/#sec-temporal.now.instant
  41. JS_DEFINE_NATIVE_FUNCTION(Now::instant)
  42. {
  43. // 1. Let ns be SystemUTCEpochNanoseconds().
  44. auto nanoseconds = system_utc_epoch_nanoseconds(vm);
  45. // 2. Return ! CreateTemporalInstant(ns).
  46. return MUST(create_temporal_instant(vm, BigInt::create(vm, move(nanoseconds))));
  47. }
  48. // 2.2.3 Temporal.Now.plainDateTimeISO ( [ temporalTimeZoneLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.now.plaindatetimeiso
  49. JS_DEFINE_NATIVE_FUNCTION(Now::plain_date_time_iso)
  50. {
  51. auto temporal_time_zone_like = vm.argument(0);
  52. // 1. Let isoDateTime be ? SystemDateTime(temporalTimeZoneLike).
  53. auto iso_date_time = TRY(system_date_time(vm, temporal_time_zone_like));
  54. // 2. Return ! CreateTemporalDateTime(isoDateTime, "iso8601").
  55. return MUST(create_temporal_date_time(vm, iso_date_time, "iso8601"_string));
  56. }
  57. // 2.2.5 Temporal.Now.plainDateISO ( [ temporalTimeZoneLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.now.plaindateiso
  58. JS_DEFINE_NATIVE_FUNCTION(Now::plain_date_iso)
  59. {
  60. auto temporal_time_zone_like = vm.argument(0);
  61. // 1. Let isoDateTime be ? SystemDateTime(temporalTimeZoneLike).
  62. auto iso_date_time = TRY(system_date_time(vm, temporal_time_zone_like));
  63. // 2. Return ! CreateTemporalDate(isoDateTime.[[ISODate]], "iso8601").
  64. return MUST(create_temporal_date(vm, iso_date_time.iso_date, "iso8601"_string));
  65. }
  66. // 2.2.6 Temporal.Now.plainTimeISO ( [ temporalTimeZoneLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.now.plaintimeiso
  67. JS_DEFINE_NATIVE_FUNCTION(Now::plain_time_iso)
  68. {
  69. auto temporal_time_zone_like = vm.argument(0);
  70. // 1. Let isoDateTime be ? SystemDateTime(temporalTimeZoneLike).
  71. auto iso_date_time = TRY(system_date_time(vm, temporal_time_zone_like));
  72. // 2. Return ! CreateTemporalTime(isoDateTime.[[Time]]).
  73. return MUST(create_temporal_time(vm, iso_date_time.time));
  74. }
  75. // 2.3.3 SystemUTCEpochNanoseconds ( ), https://tc39.es/proposal-temporal/#sec-temporal-systemutcepochnanoseconds
  76. Crypto::SignedBigInteger system_utc_epoch_nanoseconds(VM& vm)
  77. {
  78. // 1. Let global be GetGlobalObject().
  79. auto const& global = vm.get_global_object();
  80. // 2. Let nowNs be HostSystemUTCEpochNanoseconds(global).
  81. auto now_ns = vm.host_system_utc_epoch_nanoseconds(global);
  82. // 3. Return ℤ(nowNs).
  83. return now_ns;
  84. }
  85. // 2.3.4 SystemDateTime ( temporalTimeZoneLike ), https://tc39.es/proposal-temporal/#sec-temporal-systemdatetime
  86. ThrowCompletionOr<ISODateTime> system_date_time(VM& vm, Value temporal_time_zone_like)
  87. {
  88. String time_zone;
  89. // 1. If temporalTimeZoneLike is undefined, then
  90. if (temporal_time_zone_like.is_undefined()) {
  91. // a. Let timeZone be SystemTimeZoneIdentifier().
  92. time_zone = system_time_zone_identifier();
  93. }
  94. // 2. Else,
  95. else {
  96. // a. Let timeZone be ? ToTemporalTimeZoneIdentifier(temporalTimeZoneLike).
  97. time_zone = TRY(to_temporal_time_zone_identifier(vm, temporal_time_zone_like));
  98. }
  99. // 3. Let epochNs be SystemUTCEpochNanoseconds().
  100. auto epoch_nanoseconds = system_utc_epoch_nanoseconds(vm);
  101. // 4. Return GetISODateTimeFor(timeZone, epochNs).
  102. return get_iso_date_time_for(time_zone, epoch_nanoseconds);
  103. }
  104. }