DateTimeFormat.h (7764B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef builtin_intl_DateTimeFormat_h 8 #define builtin_intl_DateTimeFormat_h 9 10 #include "builtin/SelfHostingDefines.h" 11 #include "builtin/temporal/Calendar.h" 12 #include "builtin/temporal/TimeZone.h" 13 #include "js/Class.h" 14 #include "vm/NativeObject.h" 15 16 namespace mozilla::intl { 17 class DateTimeFormat; 18 class DateIntervalFormat; 19 } // namespace mozilla::intl 20 21 namespace js { 22 23 enum class DateTimeValueKind { 24 Number, 25 TemporalDate, 26 TemporalTime, 27 TemporalDateTime, 28 TemporalYearMonth, 29 TemporalMonthDay, 30 TemporalZonedDateTime, 31 TemporalInstant, 32 }; 33 34 class DateTimeFormatObject : public NativeObject { 35 public: 36 static const JSClass class_; 37 static const JSClass& protoClass_; 38 39 static constexpr uint32_t INTERNALS_SLOT = 0; 40 static constexpr uint32_t DATE_FORMAT_SLOT = 1; 41 static constexpr uint32_t DATE_INTERVAL_FORMAT_SLOT = 2; 42 static constexpr uint32_t DATE_TIME_VALUE_KIND_SLOT = 3; 43 static constexpr uint32_t CALENDAR_SLOT = 4; 44 static constexpr uint32_t TIMEZONE_SLOT = 5; 45 static constexpr uint32_t SLOT_COUNT = 6; 46 47 static_assert(INTERNALS_SLOT == INTL_INTERNALS_OBJECT_SLOT, 48 "INTERNALS_SLOT must match self-hosting define for internals " 49 "object slot"); 50 51 // Estimated memory use for UDateFormat (see IcuMemoryUsage). 52 static constexpr size_t UDateFormatEstimatedMemoryUse = 72440; 53 54 // Estimated memory use for UDateIntervalFormat (see IcuMemoryUsage). 55 static constexpr size_t UDateIntervalFormatEstimatedMemoryUse = 175646; 56 57 mozilla::intl::DateTimeFormat* getDateFormat() const { 58 const auto& slot = getFixedSlot(DATE_FORMAT_SLOT); 59 if (slot.isUndefined()) { 60 return nullptr; 61 } 62 return static_cast<mozilla::intl::DateTimeFormat*>(slot.toPrivate()); 63 } 64 65 void setDateFormat(mozilla::intl::DateTimeFormat* dateFormat) { 66 setFixedSlot(DATE_FORMAT_SLOT, PrivateValue(dateFormat)); 67 } 68 69 mozilla::intl::DateIntervalFormat* getDateIntervalFormat() const { 70 const auto& slot = getFixedSlot(DATE_INTERVAL_FORMAT_SLOT); 71 if (slot.isUndefined()) { 72 return nullptr; 73 } 74 return static_cast<mozilla::intl::DateIntervalFormat*>(slot.toPrivate()); 75 } 76 77 void setDateIntervalFormat( 78 mozilla::intl::DateIntervalFormat* dateIntervalFormat) { 79 setFixedSlot(DATE_INTERVAL_FORMAT_SLOT, PrivateValue(dateIntervalFormat)); 80 } 81 82 DateTimeValueKind getDateTimeValueKind() const { 83 const auto& slot = getFixedSlot(DATE_TIME_VALUE_KIND_SLOT); 84 if (slot.isUndefined()) { 85 return DateTimeValueKind::Number; 86 } 87 return static_cast<DateTimeValueKind>(slot.toInt32()); 88 } 89 90 void setDateTimeValueKind(DateTimeValueKind kind) { 91 setFixedSlot(DATE_TIME_VALUE_KIND_SLOT, 92 Int32Value(static_cast<int32_t>(kind))); 93 } 94 95 temporal::CalendarValue getCalendar() const { 96 const auto& slot = getFixedSlot(CALENDAR_SLOT); 97 if (slot.isUndefined()) { 98 return temporal::CalendarValue(); 99 } 100 return temporal::CalendarValue(slot); 101 } 102 103 void setCalendar(const temporal::CalendarValue& calendar) { 104 setFixedSlot(CALENDAR_SLOT, calendar.toSlotValue()); 105 } 106 107 temporal::TimeZoneValue getTimeZone() const { 108 const auto& slot = getFixedSlot(TIMEZONE_SLOT); 109 if (slot.isUndefined()) { 110 return temporal::TimeZoneValue(); 111 } 112 return temporal::TimeZoneValue(slot); 113 } 114 115 void setTimeZone(const temporal::TimeZoneValue& timeZone) { 116 setFixedSlot(TIMEZONE_SLOT, timeZone.toSlotValue()); 117 } 118 119 void maybeClearCache(DateTimeValueKind kind); 120 121 private: 122 static const JSClassOps classOps_; 123 static const ClassSpec classSpec_; 124 125 static void finalize(JS::GCContext* gcx, JSObject* obj); 126 }; 127 128 /** 129 * Returns an array with the calendar type identifiers per Unicode 130 * Technical Standard 35, Unicode Locale Data Markup Language, for the 131 * supported calendars for the given locale. The default calendar is 132 * element 0. 133 * 134 * Usage: calendars = intl_availableCalendars(locale) 135 */ 136 [[nodiscard]] extern bool intl_availableCalendars(JSContext* cx, unsigned argc, 137 JS::Value* vp); 138 139 /** 140 * Returns the calendar type identifier per Unicode Technical Standard 35, 141 * Unicode Locale Data Markup Language, for the default calendar for the given 142 * locale. 143 * 144 * Usage: calendar = intl_defaultCalendar(locale) 145 */ 146 [[nodiscard]] extern bool intl_defaultCalendar(JSContext* cx, unsigned argc, 147 JS::Value* vp); 148 149 /** 150 * Returns a String value representing x (which must be a Number value) 151 * according to the effective locale and the formatting options of the 152 * given DateTimeFormat. 153 * 154 * Spec: ECMAScript Internationalization API Specification, 12.3.2. 155 * 156 * Usage: formatted = intl_FormatDateTime(dateTimeFormat, x, formatToParts) 157 */ 158 [[nodiscard]] extern bool intl_FormatDateTime(JSContext* cx, unsigned argc, 159 JS::Value* vp); 160 161 /** 162 * Returns a String value representing the range between x and y (which both 163 * must be Number values) according to the effective locale and the formatting 164 * options of the given DateTimeFormat. 165 * 166 * Spec: Intl.DateTimeFormat.prototype.formatRange proposal 167 * 168 * Usage: formatted = intl_FormatDateTimeRange(dateTimeFmt, x, y, formatToParts) 169 */ 170 [[nodiscard]] extern bool intl_FormatDateTimeRange(JSContext* cx, unsigned argc, 171 JS::Value* vp); 172 173 /** 174 * Extracts the resolved components from a DateTimeFormat and applies them to 175 * the object for resolved components. 176 * 177 * Usage: intl_resolveDateTimeFormatComponents(dateTimeFormat, resolved) 178 */ 179 [[nodiscard]] extern bool intl_resolveDateTimeFormatComponents(JSContext* cx, 180 unsigned argc, 181 JS::Value* vp); 182 183 namespace intl { 184 185 enum class DateTimeFormatKind { 186 /** 187 * Call CreateDateTimeFormat with `required = Any` and `defaults = All`. 188 */ 189 All, 190 191 /** 192 * Call CreateDateTimeFormat with `required = Date` and `defaults = Date`. 193 */ 194 Date, 195 196 /** 197 * Call CreateDateTimeFormat with `required = Time` and `defaults = Time`. 198 */ 199 Time, 200 }; 201 202 /** 203 * Returns a new instance of the standard built-in DateTimeFormat constructor. 204 */ 205 [[nodiscard]] extern DateTimeFormatObject* CreateDateTimeFormat( 206 JSContext* cx, JS::Handle<JS::Value> locales, JS::Handle<JS::Value> options, 207 DateTimeFormatKind kind); 208 209 /** 210 * Returns a possibly cached instance of the standard built-in DateTimeFormat 211 * constructor. 212 */ 213 [[nodiscard]] extern DateTimeFormatObject* GetOrCreateDateTimeFormat( 214 JSContext* cx, JS::Handle<JS::Value> locales, JS::Handle<JS::Value> options, 215 DateTimeFormatKind kind); 216 217 /** 218 * Returns a String value representing |millis| (which must be a valid time 219 * value) according to the effective locale and the formatting options of the 220 * given DateTimeFormat. 221 */ 222 [[nodiscard]] extern bool FormatDateTime( 223 JSContext* cx, JS::Handle<DateTimeFormatObject*> dateTimeFormat, 224 double millis, JS::MutableHandle<JS::Value> result); 225 226 /** 227 * Shared `toLocaleString` implementation for Temporal objects. 228 */ 229 [[nodiscard]] extern bool TemporalObjectToLocaleString( 230 JSContext* cx, const JS::CallArgs& args, DateTimeFormatKind formatKind, 231 JS::Handle<JS::Value> toLocaleStringTimeZone = JS::UndefinedHandleValue); 232 233 } // namespace intl 234 235 } // namespace js 236 237 #endif /* builtin_intl_DateTimeFormat_h */