summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/Date.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/builtin/Date.js')
-rw-r--r--js/src/builtin/Date.js170
1 files changed, 170 insertions, 0 deletions
diff --git a/js/src/builtin/Date.js b/js/src/builtin/Date.js
new file mode 100644
index 0000000000..20bc924f05
--- /dev/null
+++ b/js/src/builtin/Date.js
@@ -0,0 +1,170 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#if JS_HAS_INTL_API
+// This cache, once primed, has these properties:
+//
+// runtimeDefaultLocale:
+// Locale information provided by the embedding, guiding SpiderMonkey's
+// selection of a default locale. See RuntimeDefaultLocale(), whose
+// value controls the value returned by DefaultLocale() that's what's
+// *actually* used.
+// icuDefaultTimeZone:
+// Time zone information provided by ICU. See intl_defaultTimeZone(),
+// whose value controls the value returned by DefaultTimeZone() that's
+// what's *actually* used.
+// formatters:
+// A Record storing formatters consistent with the above
+// runtimeDefaultLocale/localTZA values, for use with the appropriate
+// ES6 toLocale*String Date method when called with its first two
+// arguments having the value |undefined|.
+//
+// The "formatters" Record has (some subset of) these properties, as determined
+// by all values of the first argument passed to |GetCachedFormat|:
+//
+// dateTimeFormat: for Date's toLocaleString operation
+// dateFormat: for Date's toLocaleDateString operation
+// timeFormat: for Date's toLocaleTimeString operation
+//
+// Using this cache, then, requires
+// 1) verifying the current runtimeDefaultLocale/icuDefaultTimeZone are
+// consistent with cached values, then
+// 2) seeing if the desired formatter is cached and returning it if so, or else
+// 3) create the desired formatter and store and return it.
+var dateTimeFormatCache = new Record();
+
+
+/**
+ * Get a cached DateTimeFormat formatter object, created like so:
+ *
+ * var opts = ToDateTimeOptions(undefined, required, defaults);
+ * return new Intl.DateTimeFormat(undefined, opts);
+ *
+ * |format| must be a key from the "formatters" Record described above.
+ */
+function GetCachedFormat(format, required, defaults) {
+ assert(format === "dateTimeFormat" ||
+ format === "dateFormat" ||
+ format === "timeFormat",
+ "unexpected format key: please update the comment by " +
+ "dateTimeFormatCache");
+
+ var formatters;
+ if (!IsRuntimeDefaultLocale(dateTimeFormatCache.runtimeDefaultLocale) ||
+ !intl_isDefaultTimeZone(dateTimeFormatCache.icuDefaultTimeZone))
+ {
+ formatters = dateTimeFormatCache.formatters = new Record();
+ dateTimeFormatCache.runtimeDefaultLocale = RuntimeDefaultLocale();
+ dateTimeFormatCache.icuDefaultTimeZone = intl_defaultTimeZone();
+ } else {
+ formatters = dateTimeFormatCache.formatters;
+ }
+
+ var fmt = formatters[format];
+ if (fmt === undefined) {
+ var options = ToDateTimeOptions(undefined, required, defaults);
+ fmt = formatters[format] = intl_DateTimeFormat(undefined, options);
+ }
+
+ return fmt;
+}
+
+/**
+ * Format this Date object into a date and time string, using the locale and
+ * formatting options provided.
+ *
+ * Spec: ECMAScript Language Specification, 5.1 edition, 15.9.5.5.
+ * Spec: ECMAScript Internationalization API Specification, 13.3.1.
+ */
+function Date_toLocaleString() {
+ // Steps 1-2.
+ var x = callFunction(ThisTimeValue, this, DATE_METHOD_LOCALE_STRING);
+ if (Number_isNaN(x))
+ return "Invalid Date";
+
+ // Steps 3-4.
+ var locales = arguments.length > 0 ? arguments[0] : undefined;
+ var options = arguments.length > 1 ? arguments[1] : undefined;
+
+ // Step 5-6.
+ var dateTimeFormat;
+ if (locales === undefined && options === undefined) {
+ // This cache only optimizes for the old ES5 toLocaleString without
+ // locales and options.
+ dateTimeFormat = GetCachedFormat("dateTimeFormat", "any", "all");
+ } else {
+ options = ToDateTimeOptions(options, "any", "all");
+ dateTimeFormat = intl_DateTimeFormat(locales, options);
+ }
+
+ // Step 7.
+ return intl_FormatDateTime(dateTimeFormat, x, /* formatToParts = */ false);
+}
+
+
+/**
+ * Format this Date object into a date string, using the locale and formatting
+ * options provided.
+ *
+ * Spec: ECMAScript Language Specification, 5.1 edition, 15.9.5.6.
+ * Spec: ECMAScript Internationalization API Specification, 13.3.2.
+ */
+function Date_toLocaleDateString() {
+ // Steps 1-2.
+ var x = callFunction(ThisTimeValue, this, DATE_METHOD_LOCALE_DATE_STRING);
+ if (Number_isNaN(x))
+ return "Invalid Date";
+
+ // Steps 3-4.
+ var locales = arguments.length > 0 ? arguments[0] : undefined;
+ var options = arguments.length > 1 ? arguments[1] : undefined;
+
+ // Step 5-6.
+ var dateTimeFormat;
+ if (locales === undefined && options === undefined) {
+ // This cache only optimizes for the old ES5 toLocaleDateString without
+ // locales and options.
+ dateTimeFormat = GetCachedFormat("dateFormat", "date", "date");
+ } else {
+ options = ToDateTimeOptions(options, "date", "date");
+ dateTimeFormat = intl_DateTimeFormat(locales, options);
+ }
+
+ // Step 7.
+ return intl_FormatDateTime(dateTimeFormat, x, /* formatToParts = */ false);
+}
+
+
+/**
+ * Format this Date object into a time string, using the locale and formatting
+ * options provided.
+ *
+ * Spec: ECMAScript Language Specification, 5.1 edition, 15.9.5.7.
+ * Spec: ECMAScript Internationalization API Specification, 13.3.3.
+ */
+function Date_toLocaleTimeString() {
+ // Steps 1-2.
+ var x = callFunction(ThisTimeValue, this, DATE_METHOD_LOCALE_TIME_STRING);
+ if (Number_isNaN(x))
+ return "Invalid Date";
+
+ // Steps 3-4.
+ var locales = arguments.length > 0 ? arguments[0] : undefined;
+ var options = arguments.length > 1 ? arguments[1] : undefined;
+
+ // Step 5-6.
+ var dateTimeFormat;
+ if (locales === undefined && options === undefined) {
+ // This cache only optimizes for the old ES5 toLocaleTimeString without
+ // locales and options.
+ dateTimeFormat = GetCachedFormat("timeFormat", "time", "time");
+ } else {
+ options = ToDateTimeOptions(options, "time", "time");
+ dateTimeFormat = intl_DateTimeFormat(locales, options);
+ }
+
+ // Step 7.
+ return intl_FormatDateTime(dateTimeFormat, x, /* formatToParts = */ false);
+}
+#endif // JS_HAS_INTL_API