Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / js / src / builtin / Date.js
blobf32d593db515c4e3da217d220ed2f7dd316b9fd7
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #if JS_HAS_INTL_API
6 // This cache, once primed, has these properties:
7 //
8 //   runtimeDefaultLocale:
9 //     Locale information provided by the embedding, guiding SpiderMonkey's
10 //     selection of a default locale.  See intl_RuntimeDefaultLocale(), whose
11 //     value controls the value returned by DefaultLocale() that's what's
12 //     *actually* used.
13 //   icuDefaultTimeZone:
14 //     Time zone information provided by ICU. See intl_defaultTimeZone(),
15 //     whose value controls the value returned by DefaultTimeZone() that's
16 //     what's *actually* used.
17 //   formatters:
18 //     A Record storing formatters consistent with the above
19 //     runtimeDefaultLocale/localTZA values, for use with the appropriate
20 //     ES6 toLocale*String Date method when called with its first two
21 //     arguments having the value |undefined|.
23 // The "formatters" Record has (some subset of) these properties, as determined
24 // by all values of the first argument passed to |GetCachedFormat|:
26 //   dateTimeFormat: for Date's toLocaleString operation
27 //   dateFormat: for Date's toLocaleDateString operation
28 //   timeFormat: for Date's toLocaleTimeString operation
30 // Using this cache, then, requires
31 // 1) verifying the current runtimeDefaultLocale/icuDefaultTimeZone are
32 //    consistent with cached values, then
33 // 2) seeing if the desired formatter is cached and returning it if so, or else
34 // 3) create the desired formatter and store and return it.
35 var dateTimeFormatCache = new_Record();
37 /**
38  * Get a cached DateTimeFormat formatter object, created like so:
39  *
40  *   CreateDateTimeFormat(undefined, undefined, required, defaults);
41  *
42  * |format| must be a key from the "formatters" Record described above.
43  */
44 function GetCachedFormat(format, required, defaults) {
45   assert(
46     format === "dateTimeFormat" ||
47       format === "dateFormat" ||
48       format === "timeFormat",
49     "unexpected format key: please update the comment by dateTimeFormatCache"
50   );
52   var formatters;
53   if (
54     !intl_IsRuntimeDefaultLocale(dateTimeFormatCache.runtimeDefaultLocale) ||
55     !intl_isDefaultTimeZone(dateTimeFormatCache.icuDefaultTimeZone)
56   ) {
57     formatters = dateTimeFormatCache.formatters = new_Record();
58     dateTimeFormatCache.runtimeDefaultLocale = intl_RuntimeDefaultLocale();
59     dateTimeFormatCache.icuDefaultTimeZone = intl_defaultTimeZone();
60   } else {
61     formatters = dateTimeFormatCache.formatters;
62   }
64   var fmt = formatters[format];
65   if (fmt === undefined) {
66     fmt = formatters[format] = intl_CreateDateTimeFormat(undefined, undefined, required, defaults);
67   }
69   return fmt;
72 /**
73  * Format this Date object into a date and time string, using the locale and
74  * formatting options provided.
75  *
76  * Spec: ECMAScript Language Specification, 5.1 edition, 15.9.5.5.
77  * Spec: ECMAScript Internationalization API Specification, 13.3.1.
78  */
79 function Date_toLocaleString() {
80   // Steps 1-2.
81   var x = callFunction(ThisTimeValue, this, DATE_METHOD_LOCALE_STRING);
82   if (Number_isNaN(x)) {
83     return "Invalid Date";
84   }
86   // Steps 3-4.
87   var locales = ArgumentsLength() ? GetArgument(0) : undefined;
88   var options = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
90   // Step 5-6.
91   var dateTimeFormat;
92   if (locales === undefined && options === undefined) {
93     // This cache only optimizes for the old ES5 toLocaleString without
94     // locales and options.
95     dateTimeFormat = GetCachedFormat("dateTimeFormat", "any", "all");
96   } else {
97     dateTimeFormat = intl_CreateDateTimeFormat(locales, options, "any", "all");
98   }
100   // Step 7.
101   return intl_FormatDateTime(dateTimeFormat, x, /* formatToParts = */ false);
105  * Format this Date object into a date string, using the locale and formatting
106  * options provided.
108  * Spec: ECMAScript Language Specification, 5.1 edition, 15.9.5.6.
109  * Spec: ECMAScript Internationalization API Specification, 13.3.2.
110  */
111 function Date_toLocaleDateString() {
112   // Steps 1-2.
113   var x = callFunction(ThisTimeValue, this, DATE_METHOD_LOCALE_DATE_STRING);
114   if (Number_isNaN(x)) {
115     return "Invalid Date";
116   }
118   // Steps 3-4.
119   var locales = ArgumentsLength() ? GetArgument(0) : undefined;
120   var options = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
122   // Step 5-6.
123   var dateTimeFormat;
124   if (locales === undefined && options === undefined) {
125     // This cache only optimizes for the old ES5 toLocaleDateString without
126     // locales and options.
127     dateTimeFormat = GetCachedFormat("dateFormat", "date", "date");
128   } else {
129     dateTimeFormat = intl_CreateDateTimeFormat(locales, options, "date", "date");
130   }
132   // Step 7.
133   return intl_FormatDateTime(dateTimeFormat, x, /* formatToParts = */ false);
137  * Format this Date object into a time string, using the locale and formatting
138  * options provided.
140  * Spec: ECMAScript Language Specification, 5.1 edition, 15.9.5.7.
141  * Spec: ECMAScript Internationalization API Specification, 13.3.3.
142  */
143 function Date_toLocaleTimeString() {
144   // Steps 1-2.
145   var x = callFunction(ThisTimeValue, this, DATE_METHOD_LOCALE_TIME_STRING);
146   if (Number_isNaN(x)) {
147     return "Invalid Date";
148   }
150   // Steps 3-4.
151   var locales = ArgumentsLength() ? GetArgument(0) : undefined;
152   var options = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
154   // Step 5-6.
155   var dateTimeFormat;
156   if (locales === undefined && options === undefined) {
157     // This cache only optimizes for the old ES5 toLocaleTimeString without
158     // locales and options.
159     dateTimeFormat = GetCachedFormat("timeFormat", "time", "time");
160   } else {
161     dateTimeFormat = intl_CreateDateTimeFormat(locales, options, "time", "time");
162   }
164   // Step 7.
165   return intl_FormatDateTime(dateTimeFormat, x, /* formatToParts = */ false);
167 #endif  // JS_HAS_INTL_API