Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shared/js/l10n_date.js
diff options
context:
space:
mode:
Diffstat (limited to 'shared/js/l10n_date.js')
-rw-r--r--shared/js/l10n_date.js141
1 files changed, 141 insertions, 0 deletions
diff --git a/shared/js/l10n_date.js b/shared/js/l10n_date.js
new file mode 100644
index 0000000..eb461a3
--- /dev/null
+++ b/shared/js/l10n_date.js
@@ -0,0 +1,141 @@
+/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+
+'use strict';
+
+/**
+ * This lib relies on `l10n.js' to implement localizable date/time strings.
+ *
+ * The proposed `DateTimeFormat' object should provide all the features that are
+ * planned for the `Intl.DateTimeFormat' constructor, but the API does not match
+ * exactly the ES-i18n draft.
+ * - https://bugzilla.mozilla.org/show_bug.cgi?id=769872
+ * - http://wiki.ecmascript.org/doku.php?id=globalization:specification_drafts
+ *
+ * Besides, this `DateTimeFormat' object provides two features that aren't
+ * planned in the ES-i18n spec:
+ * - a `toLocaleFormat()' that really works (i.e. fully translated);
+ * - a `fromNow()' method to handle relative dates ("pretty dates").
+ *
+ * WARNING: this library relies on the non-standard `toLocaleFormat()' method,
+ * which is specific to Firefox -- no other browser is supported.
+ */
+
+navigator.mozL10n.DateTimeFormat = function(locales, options) {
+ var _ = navigator.mozL10n.get;
+
+ // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleFormat
+ function localeFormat(d, format) {
+ var tokens = format.match(/(%E.|%O.|%.)/g);
+
+ for (var i = 0; tokens && i < tokens.length; i++) {
+ var value = '';
+
+ // http://pubs.opengroup.org/onlinepubs/007908799/xsh/strftime.html
+ switch (tokens[i]) {
+ // localized day/month names
+ case '%a':
+ value = _('weekday-' + d.getDay() + '-short');
+ break;
+ case '%A':
+ value = _('weekday-' + d.getDay() + '-long');
+ break;
+ case '%b':
+ case '%h':
+ value = _('month-' + d.getMonth() + '-short');
+ break;
+ case '%B':
+ value = _('month-' + d.getMonth() + '-long');
+ break;
+
+ // like %H, but in 12-hour format and without any leading zero
+ case '%I':
+ value = d.getHours() % 12 || 12;
+ break;
+
+ // like %d, without any leading zero
+ case '%e':
+ value = d.getDate();
+ break;
+
+ // localized date/time strings
+ case '%c':
+ case '%x':
+ case '%X':
+ // ensure the localized format string doesn't contain any %c|%x|%X
+ var tmp = _('dateTimeFormat_' + tokens[i]);
+ if (tmp && !(/(%c|%x|%X)/).test(tmp)) {
+ value = localeFormat(d, tmp);
+ }
+ break;
+
+ // other tokens don't require any localization
+ }
+
+ format = format.replace(tokens[i], value || d.toLocaleFormat(tokens[i]));
+ }
+
+ return format;
+ }
+
+ // variant of John Resig's PrettyDate.js
+ function prettyDate(time, useCompactFormat) {
+ switch (time.constructor) {
+ case String: // timestamp
+ time = parseInt(time);
+ break;
+ case Date:
+ time = time.getTime();
+ break;
+ }
+
+ var secDiff = (Date.now() - time) / 1000;
+ if (isNaN(secDiff)) {
+ return _('incorrectDate');
+ }
+
+ var f = useCompactFormat ? '-short' : '-long';
+
+ if (secDiff >= 0) { // past
+ var dayDiff = Math.floor(secDiff / 86400);
+ if (secDiff < 3600) {
+ return _('minutesAgo' + f, { m: Math.floor(secDiff / 60) });
+ } else if (dayDiff === 0) {
+ return _('hoursAgo' + f, { h: Math.floor(secDiff / 3600) });
+ } else if (dayDiff < 10) {
+ return _('daysAgo' + f, { d: dayDiff });
+ }
+ }
+
+ if (secDiff < 0) { // future
+ secDiff = -secDiff;
+ dayDiff = Math.floor(secDiff / 86400);
+ if (secDiff < 3600) {
+ return _('inMinutes' + f, { m: Math.floor(secDiff / 60) });
+ } else if (dayDiff === 0) {
+ return _('inHours' + f, { h: Math.floor(secDiff / 3600) });
+ } else if (dayDiff < 10) {
+ return _('inDays' + f, { d: dayDiff });
+ }
+ }
+
+ // too far: return an absolute date
+ return localeFormat(new Date(time), '%x');
+ }
+
+ // API
+ return {
+ localeDateString: function localeDateString(d) {
+ return localeFormat(d, '%x');
+ },
+ localeTimeString: function localeTimeString(d) {
+ return localeFormat(d, '%X');
+ },
+ localeString: function localeString(d) {
+ return localeFormat(d, '%c');
+ },
+ localeFormat: localeFormat,
+ fromNow: prettyDate
+ };
+};
+