Bug 1073922 - Hard-coded date format in the calendar views. r=philipp
authorDecathlon <bv1578@gmail.com>
Thu, 27 Nov 2014 09:16:53 +0100
changeset 21459 3f79b6396819e52316dc0aa066da6b4cfa53e70f
parent 21458 e7fc94abf423190dc074e3ab1e0f921dee352599
child 21460 08168dc1fecf7ca8295751683cfe298b56af73ee
push id1305
push usermbanner@mozilla.com
push dateMon, 23 Feb 2015 19:48:12 +0000
treeherdercomm-beta@3ae4f13858fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersphilipp
bugs1073922
Bug 1073922 - Hard-coded date format in the calendar views. r=philipp
calendar/base/content/calendar-base-view.xml
calendar/base/content/calendar-month-view.xml
calendar/base/modules/calRecurrenceUtils.jsm
calendar/base/public/calIDateTimeFormatter.idl
calendar/base/src/calDateTimeFormatter.js
calendar/locales/en-US/chrome/calendar/calendar-event-dialog.properties
calendar/locales/en-US/chrome/calendar/calendar.properties
calendar/locales/en-US/chrome/calendar/dateFormat.properties
--- a/calendar/base/content/calendar-base-view.xml
+++ b/calendar/base/content/calendar-base-view.xml
@@ -871,20 +871,25 @@
       </property>
 
       <property name="date">
         <getter><![CDATA[
           return this.mDate;
         ]]></getter>
         <setter><![CDATA[
           this.mDate = val;
-          this.shortName.setAttribute("value", getDateFormatter().shortDayName(val.weekday) + " " +
-                                               getDateFormatter().formatDateWithoutYear(val));
-          this.longName.setAttribute("value", getDateFormatter().dayName(val.weekday) + " " +
-                                              getDateFormatter().formatDateWithoutYear(val));
+          let dateFormatter = cal.getDateFormatter();
+          let label = cal.calGetString("calendar", "dayHeaderLabel",
+                                       [dateFormatter.shortDayName(val.weekday),
+                                        dateFormatter.formatDateWithoutYear(val)]);
+          this.shortName.setAttribute("value", label);
+          label = cal.calGetString("calendar", "dayHeaderLabel",
+                                   [dateFormatter.dayName(val.weekday),
+                                    dateFormatter.formatDateWithoutYear(val)]);
+          this.longName.setAttribute("value", label);
           return val;
         ]]></setter>
       </property>
 
       <property name="shortWeekNames">
         <getter><![CDATA[
         ]]></getter>
         <setter><![CDATA[
--- a/calendar/base/content/calendar-month-view.xml
+++ b/calendar/base/content/calendar-month-view.xml
@@ -171,18 +171,17 @@
             return val;
           }
           this.mShowMonthLabel = val;
 
           if (!this.mDate) {
             return val;
           }
           if (val) {
-            let monthName = calGetString("dateFormat", "month." + (this.mDate.month + 1) + ".Mmm");
-            this.setAttribute("value", this.mDate.day + " " + monthName);
+            this.setAttribute("value", getDateFormatter().formatDateWithoutYear(this.mDate));
           } else {
             this.setAttribute("value", this.mDate.day);
           }
           return val;
         ]]></setter>
       </property>
 
       <method name="setDate">
--- a/calendar/base/modules/calRecurrenceUtils.jsm
+++ b/calendar/base/modules/calRecurrenceUtils.jsm
@@ -50,16 +50,17 @@ function recurrenceRule2String(recurrenc
                 return aRuleString + nounClass.substr(0, 1).toUpperCase() +
                        nounClass.substr(1);
             }
             function pluralWeekday(aDayString) {
                 let plural = getRString("pluralForWeekdays") == "true";
                 return (plural ? aDayString + "Plural" : aDayString);
             }
 
+            let dateFormatter = cal.getDateFormatter();
             let ruleString;
             if (rule.type == 'DAILY') {
                 if (checkRecurrenceRule(rule, ['BYDAY'])) {
                     let days = rule.getComponent("BYDAY", {});
                     let weekdays = [2, 3, 4, 5, 6];
                     if (weekdays.length == days.length) {
                         let i;
                         for (i = 0; i < weekdays.length; i++) {
@@ -186,25 +187,23 @@ function recurrenceRule2String(recurrenc
                             ruleString = getRString("monthlyEveryDayOfNth");
                             ruleString = PluralForm.get(rule.interval, ruleString)
                                                    .replace("#2", rule.interval);
                         } else {
                             // i.e. one or more monthdays every N months.
 
                             // Build a string with a list of days separated with commas.
                             let day_string = "";
-                            let ordinalSymbols = getRString("monthlyDaysOfNth_ordSymbol").split(",");
                             let lastDay = false;
                             for (let i = 0; i < component.length; i++) {
                                 if (component[i] == -1) {
                                     lastDay = true;
                                     continue;
                                 }
-                                let dayOrdinalSymbol = ordinalSymbols[component[i] -1] || ordinalSymbols[0];
-                                day_string += component[i] + dayOrdinalSymbol + ", ";
+                                day_string += dateFormatter.formatDayWithOrdinal(component[i]) + ", ";
                             }
                             if (lastDay) {
                                 day_string += getRString("monthlyLastDay") + ", ";
                             }
                             day_string = day_string.slice(0,-2)
                                          .replace(/,(?= [^,]*$)/, ' ' + getRString("repeatDetailsAnd"));
 
                             // Add the word "day" in plural form to the list of days then
@@ -226,17 +225,18 @@ function recurrenceRule2String(recurrenc
                 if (checkRecurrenceRule(rule, ['BYMONTH']) &&
                     checkRecurrenceRule(rule, ['BYMONTHDAY'])) {
                     let bymonthday = rule.getComponent("BYMONTHDAY", {});
 
                     if (bymonth.length == 1 && bymonthday.length == 1) {
                         let monthNameString = getRString("repeatDetailsMonth" + bymonth[0]);
 
                         let yearlyString = getRString("yearlyNthOn",
-                                                      [monthNameString, bymonthday[0]]);
+                                                      [monthNameString,
+                                                       dateFormatter.formatDayWithOrdinal(bymonthday[0])]);
                         ruleString = PluralForm.get(rule.interval, yearlyString)
                                                .replace("#3", rule.interval);
                     }
                 } else if (checkRecurrenceRule(rule, ['BYMONTH']) &&
                            checkRecurrenceRule(rule, ['BYDAY'])) {
                     let byday = rule.getComponent("BYDAY", {});
 
                     if (bymonth.length == 1 && byday.length == 1) {
@@ -269,17 +269,16 @@ function recurrenceRule2String(recurrenc
                     let yearlyString = getRString("yearlyNthOn",
                                                   [monthNameString, startDate.day]);
                     ruleString = PluralForm.get(rule.interval, yearlyString)
                                            .replace("#3", rule.interval);
                 }
             }
 
             let kDefaultTimezone = cal.calendarDefaultTimezone();
-            let dateFormatter = cal.getDateFormatter();
 
             let detailsString;
             if (!endDate || allDay) {
                 if (rule.isFinite) {
                     if (rule.isByCount) {
                         let countString = getRString("repeatCountAllDay",
                             [ruleString,
                              dateFormatter.formatDateShort(startDate)]);
--- a/calendar/base/public/calIDateTimeFormatter.idl
+++ b/calendar/base/public/calIDateTimeFormatter.idl
@@ -3,17 +3,17 @@
  * 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/. */
 
 #include "nsISupports.idl"
 
 interface calIDateTime;
 interface calIItemBase;
 
-[scriptable, uuid(17101743-f016-4fb2-90dd-0c043aa44579)]
+[scriptable, uuid(69741510-5f5d-11e4-9803-0800200c9a66)]
 interface calIDateTimeFormatter : nsISupports
 {
     /**
      * Format a date in either short or long format, depending on the
      * users preference
      *
      * @see
      *     formatDateShort
@@ -110,16 +110,29 @@ interface calIDateTimeFormatter : nsISup
      * Format a time interval like formatInterval, but show only the time.
      *
      * @param aStartDate        The start of the interval.
      * @param aEndDate          The end of the interval.
      * @return                  The formatted time interval.
      */
     AUTF8String formatTimeInterval(in calIDateTime aStartTime,
                                    in calIDateTime aEndTime);
+
+    /**
+     * Get the monthday followed by its ordinal symbol in the current locale.
+     * e.g.  monthday 1 -> 1st
+     *       monthday 2 -> 2nd etc.
+     *
+     * @param aMonthdayIndex
+     *      a number from 1 to 31
+     * @returns
+     *      the monthday number in ordinal format in the current locale
+     */
+    AUTF8String formatDayWithOrdinal(in unsigned long aMonthdayIndex);
+
     /**
      * Get the month name
      *
      * @param aMonthIndex
      *     zero-based month number (0 is january, 11 is december)
      * @returns
      *      the month name in the current locale
      */
--- a/calendar/base/src/calDateTimeFormatter.js
+++ b/calendar/base/src/calDateTimeFormatter.js
@@ -97,30 +97,31 @@ calDateTimeFormatter.prototype = {
                                                 nsIScriptableDateFormat.dateFormatLong,
                                                 aDate.year,
                                                 aDate.month + 1,
                                                 aDate.day);
         } else {
             // HACK We are probably on Linux and want a string in long format.
             // dateService.dateFormatLong on Linux may return a short string, so
             // build our own.
-            return this.shortDayName(aDate.weekday) + " " +
-                   aDate.day + " " +
-                   this.shortMonthName(aDate.month) + " " +
-                   aDate.year;
+            return cal.calGetString("calendar", "formatDateLong",
+                                    [this.shortDayName(aDate.weekday),
+                                     this.formatDayWithOrdinal(aDate.day),
+                                     this.shortMonthName(aDate.month),
+                                     aDate.year]);
         }
     },
 
     formatDateWithoutYear: function formatDateWithoutYear(aDate) {
         // Doing this the hard way, because nsIScriptableDateFormat doesn't
         // have a way to not include the year.
         if (this.mMonthFirst) {
-            return this.shortMonthName(aDate.month) + " " + aDate.day;
+            return this.shortMonthName(aDate.month) + " " + this.formatDayWithOrdinal(aDate.day);
         } else {
-            return aDate.day + " " + this.shortMonthName(aDate.month);
+            return this.formatDayWithOrdinal(aDate.day) + " " + this.shortMonthName(aDate.month);
         }
     },
 
     formatTime: function formatTime(aDate) {
         if (aDate.isDate)
             return this.mDateStringBundle.GetStringFromName("AllDay");
 
         return this.mDateService.FormatTime("",
@@ -172,31 +173,31 @@ calDateTimeFormatter.prototype = {
         let testdate = aStartDate.clone();
         testdate.isDate = true;
         let sameDay = (testdate.compare(endDate) == 0);
         if (aStartDate.isDate) {
             // All-day interval, so we should leave out the time part
             if (sameDay) {
                 return this.formatDateLong(aStartDate);
             } else {
-                let startDay = aStartDate.day;
+                let startDay = this.formatDayWithOrdinal(aStartDate.day);
                 let startYear = aStartDate.year;
-                let endDay = endDate.day;
+                let endDay = this.formatDayWithOrdinal(endDate.day);
                 let endYear = endDate.year;
                 if (aStartDate.year != endDate.year) {
-                    let startMonthName = cal.formatMonth(aStartDate.month + 1, "calendar", "dayIntervalBetweenYears");
-                    let endMonthName = cal.formatMonth(aEndDate.month + 1, "calendar", "dayIntervalBetweenYears");
-                    return calGetString("calendar", "dayIntervalBetweenYears", [startMonthName, startDay, startYear, endMonthName, endDay, endYear]);
+                    let startMonthName = cal.formatMonth(aStartDate.month + 1, "calendar", "daysIntervalBetweenYears");
+                    let endMonthName = cal.formatMonth(aEndDate.month + 1, "calendar", "daysIntervalBetweenYears");
+                    return cal.calGetString("calendar", "daysIntervalBetweenYears", [startMonthName, startDay, startYear, endMonthName, endDay, endYear]);
                 } else if (aStartDate.month != endDate.month) {
-                    let startMonthName = cal.formatMonth(aStartDate.month + 1, "calendar", "dayIntervalBetweenMonths");
-                    let endMonthName = cal.formatMonth(aEndDate.month + 1, "calendar", "dayIntervalBetweenMonths");
-                    return calGetString("calendar", "dayIntervalBetweenMonths", [startMonthName, startDay, endMonthName, endDay, endYear]);
+                    let startMonthName = cal.formatMonth(aStartDate.month + 1, "calendar", "daysIntervalBetweenMonths");
+                    let endMonthName = cal.formatMonth(aEndDate.month + 1, "calendar", "daysIntervalBetweenMonths");
+                    return cal.calGetString("calendar", "daysIntervalBetweenMonths", [startMonthName, startDay, endMonthName, endDay, endYear]);
                 } else {
-                    let startMonthName = cal.formatMonth(aStartDate.month + 1, "calendar", "dayIntervalInMonth");
-                    return calGetString("calendar", "dayIntervalInMonth", [startMonthName, startDay, endDay, endYear]);
+                    let startMonthName = cal.formatMonth(aStartDate.month + 1, "calendar", "daysIntervalInMonth");
+                    return cal.calGetString("calendar", "daysIntervalInMonth", [startMonthName, startDay, endDay, endYear]);
                 }
             }
         } else {
             let startDateString = this.formatDate(aStartDate);
             let startTime = this.formatTime(aStartDate);
             let endDateString = this.formatDate(endDate);
             let endTime = this.formatTime(endDate);
             // non-allday, so need to return date and time
@@ -215,16 +216,22 @@ calDateTimeFormatter.prototype = {
                 // Spanning multiple days, so need to include date and time
                 // for start and end
                 // "5 Jan 2006 13:00 - 7 Jan 2006 9:00"
                 return calGetString("calendar", "datetimeIntervalOnSeveralDays", [startDateString, startTime, endDateString, endTime]);
             }
         }
     },
 
+    formatDayWithOrdinal: function formatDayWithOrdinal(aDay) {
+        let ordinalSymbols = this.mDateStringBundle.GetStringFromName("dayOrdinalSymbol").split(",");
+        let dayOrdinalSymbol = ordinalSymbols[aDay - 1] || ordinalSymbols[0];
+        return aDay + dayOrdinalSymbol;
+    },
+
     _getItemDates: function _getItemDates(aItem) {
         let start = aItem[calGetStartDateProp(aItem)];
         let end = aItem[calGetEndDateProp(aItem)];
         let kDefaultTimezone = calendarDefaultTimezone();
         // Check for tasks without start and/or due date
         if (start) {
             start = start.getInTimezone(kDefaultTimezone);
         }
--- a/calendar/locales/en-US/chrome/calendar/calendar-event-dialog.properties
+++ b/calendar/locales/en-US/chrome/calendar/calendar-event-dialog.properties
@@ -109,43 +109,27 @@ ordinalWeekdayOrder=%1$S %2$S
 # "nounclass..." must be written in 'repeatDetailsDayxNounclass' strings.
 # %1$S - list of single weekdays and/or weekdays with ordinal, article and
 #        noun class/gender when rule contains also specific day in the month
 # #2 - interval
 # e.g. "every Monday, Tuesday and the second Sunday of every month"
 monthlyEveryOfEveryNounclass1=every %1$S of every month;every %1$S of every #2 months
 monthlyEveryOfEveryNounclass2=every %1$S of every month;every %1$S of every #2 months
 
-# LOCALIZATION NOTE (monthlyDaysOfNth_ordSymbol):
-# Edit recurrence window -> Recurrence pattern -> Monthly repeat rules
-# Allows to insert a string, a character or a symbol after the numbers of a day
-# in a monthly rule monthlyDaysOfNth in order to give to each day number the
-# meaning of ordinal number (e.g.  1 -> 1st; 2 -> 2nd etc.).
-# Use a single string if the symbol used is the same for every monthday, otherwise
-# write a sequence of _31_ strings (one for every monthday) separated with commas.
-# If your language doesn't require that in monthlyDaysOfNth, leave it empty.
-# e.g.
-# monthlyDaysOfNth_ordSymbol=.
-#    -> "Occurs days 1., 2., 10. and 11. of every 2 months"
-# monthlyDaysOfNth_ordSymbol=st,nd,rd,th,th,th,th,th,th,th,th,th,th,th,th,
-#                            th,th,th,th,th,st,nd,rd,th,th,th,th,th,th,th,st
-#    -> "Occurs days 1st, 2nd, 10th and 11th of every 2 months"
-monthlyDaysOfNth_ordSymbol=
-
 # LOCALIZATION NOTE (monthlyDaysOfNth_day):
 # Edit recurrence window -> Recurrence pattern -> Monthly repeat rules
-# %1$S - day of month or a sequence of days of month, eventually with ordinal symbol
-#        coming from monthlyDaysOfNth_ordSymbol, separated with commas;
+# %1$S - day of month or a sequence of days of month, possibly followed by an ordinal symbol
+#        (depending on the string dayOrdinalSymbol in dateFormat.properties) separated with commas;
 # e.g. "days 3, 6 and 9" or "days 3rd, 6th and 9th"
 monthlyDaysOfNth_day=day %1$S;days %1$S
 
 # LOCALIZATION NOTE (monthlyDaysOfNth):
 # Edit recurrence window -> Recurrence pattern -> Monthly repeat rules
 # %1$S - it's the strig monthlyDaysOfNth_day: day of month or a sequence of days
-#        of month, eventually with ordinal symbol, separated with commas;
+#        of month, possibly followed by an ordinal symbol, separated with commas;
 # #2   - monthly interval
 # e.g. "days 3, 6, 9 and 12 of every 3 months"
 monthlyDaysOfNth=%1$S of every month;%1$S of every #2 months
 
 # LOCALIZATION NOTE (monthlyLastDayOfNth):
 # Edit recurrence window -> Recurrence pattern -> Monthly repeat rules
 # %1$S - day of month
 # #2 - month interval
@@ -178,20 +162,22 @@ repeatOrdinal1Nounclass2=the first
 repeatOrdinal2Nounclass2=the second
 repeatOrdinal3Nounclass2=the third
 repeatOrdinal4Nounclass2=the fourth
 repeatOrdinal5Nounclass2=the fifth
 repeatOrdinal-1Nounclass2=the last
 
 # LOCALIZATION NOTE (yearlyNthOn):
 # Edit recurrence window -> Recurrence pattern -> Yearly repeat rules
-# %1$S - month
-# %2$S - day of month
-# #3 - yearly interval
+# %1$S - month name
+# %2$S - day of month possibly followed by an ordinal symbol (depending on the string
+#           dayOrdinalSymbol in dateFormat.properties)
+# #3   - yearly interval
 # e.g. "every 3 years on December 14"
+#      "every 2 years on December 8th"
 yearlyNthOn=every %1$S %2$S;every #3 years on %1$S %2$S
 
 # LOCALIZATION NOTE (yearlyNthOnNthOfNounclass...):
 # Edit recurrence window -> Recurrence pattern -> Yearly repeat rules
 # Translate these strings according to noun class/gender of weekday (%2$S)
 # set in 'repeadDetailsDay...Nounclass' strings.
 # Nounclass1 <-> Masculine gender; Nounclass2 <-> Feminine gender.
 # Add others strings with suffix 3, 4,... for others noun classes if your
--- a/calendar/locales/en-US/chrome/calendar/calendar.properties
+++ b/calendar/locales/en-US/chrome/calendar/calendar.properties
@@ -460,60 +460,85 @@ dueInLessThanOneHour=< 1 hour
 monthInYear=%1$S %2$S
 
 # LOCALIZATION NOTE (monthInYear.monthFormat):
 # If your language requires a different declension, change this to 
 # one of the values specified in dateFormat.properties.
 # In any case, DO NOT TRANSLATE.
 monthInYear.monthFormat=nominative
 
-# LOCALIZATION NOTE (dayIntervalInMonth):
+# LOCALIZATION NOTE (formatDateLong):
+# used for display dates in long format like 'Mon 15 Oct 2008' when it's
+# impossible to retrieve the formatatted date from the OS.
+#    %1$S will be replaced with name of the day in short format;
+#    %2$S will be replaced with the day-index of the month, possibly followed by an ordinal symbol
+#         (depending on the string dayOrdinalSymbol in dateFormat.properties);
+#    %3$S will be replaced with the name of the month in short format;
+#    %4$S will be replaced with the year.
+formatDateLong=%1$S %2$S %3$S %4$S
+
+# LOCALIZATION NOTE (dayHeaderLabel):
+# used for display the labels in the header of the days in day/week views in short
+# or long format. For example: 'Monday 6 Oct.' or 'Mon. 6 Oct.'
+#    %1$S will be replaced with name of the day in short or long format
+#    %2$S will be replaced with the day-index of the month, possibly followed by an ordinal symbol
+#         (depending on the string dayOrdinalSymbol in dateFormat.properties), plus the name
+#         of the month in short format (the day/month order depends on the OS settings).
+dayHeaderLabel=%1$S %2$S
+
+# LOCALIZATION NOTE (daysIntervalInMonth):
 # used for display of intervals in the form of 'March 3 - 9, 2008'
 #    %1$S will be replaced with name of the month of the start date
-#    %2$S will be replaced with the day-index of the start date
-#    %3$S will be replaced with the day-index of the end date
+#    %2$S will be replaced with the day-index of the start date possibly followed by an ordinal symbol
+#    %3$S will be replaced with the day-index of the end date possibly followed by an ordinal symbol
 #    %4$S will be replaced with the common year of both dates
-dayIntervalInMonth=%1$S %2$S – %3$S, %4$S
+# The presence of the ordinal symbol in the day-indexes depends on the string
+# dayOrdinalSymbol in dateFormat.properties
+daysIntervalInMonth=%1$S %2$S – %3$S, %4$S
+
+# LOCALIZATION NOTE (daysIntervalInMonth.monthFormat):
+# If your language requires a different declension, change this to
+# one of the values specified in dateFormat.properties.
+# In any case, DO NOT TRANSLATE.
+daysIntervalInMonth.monthFormat=nominative
 
-# LOCALIZATION NOTE (dayIntervalInMonth.monthFormat):
+# LOCALIZATION NOTE (daysIntervalBetweenMonths):
+# used for display of intervals in the form 'September 29 - October 5, 2008'
+#    %1$S will be replaced with name of the month of the start date
+#    %2$S will be replaced with the day-index of the start date possibly followed by an ordinal symbol
+#    %3$S will be replaced with name of the month of the end date
+#    %4$S will be replaced with the day-index of the end date possibly followed by an ordinal symbol
+#    %5$S will be replaced with the commmon year of both dates
+# The presence of the ordinal symbol in the day-indexes depends on the string
+# dayOrdinalSymbol in dateFormat.properties
+daysIntervalBetweenMonths=%1$S %2$S – %3$S %4$S, %5$S
+
+# LOCALIZATION NOTE (daysIntervalBetweenMonths.monthFormat):
 # If your language requires a different declension, change this to 
 # one of the values specified in dateFormat.properties.
 # In any case, DO NOT TRANSLATE.
-dayIntervalInMonth.monthFormat=nominative
+daysIntervalBetweenMonths.monthFormat=nominative
 
-# LOCALIZATION NOTE (dayIntervalBetweenMonths):
-# used for display of intervals in the form 'September 29 - October 5, 2008'
+# LOCALIZATION NOTE (daysIntervalBetweenYears):
+# used for display of intervals in the form 'December 29, 2008 - January 4, 2009'
 #    %1$S will be replaced with name of the month of the start date
-#    %2$S will be replaced with the day-index of the start date
-#    %3$S will be replaced with name of the month of the end date
-#    %4$S will be replaced with the day-index of the end date
-#    %5$S will be replaced with the commmon year of both dates
-dayIntervalBetweenMonths=%1$S %2$S – %3$S %4$S, %5$S
+#    %2$S will be replaced with the day-index of the start date possibly followed by an ordinal symbol
+#    %3$S will be replaced with the year of the start date
+#    %4$S will be replaced with name of the month of the end date
+#    %5$S will be replaced with the day-index of the end date possibly followed by an ordinal symbol
+#    %6$S will be replaced with the year of the end date
+# The presence of the ordinal symbol in the day-indexes depends on the string
+# dayOrdinalSymbol in dateFormat.properties
+daysIntervalBetweenYears=%1$S %2$S, %3$S – %4$S %5$S, %6$S
 
-# LOCALIZATION NOTE (dayIntervalBetweenMonths.monthFormat):
-# If your language requires a different declension, change this to 
+# LOCALIZATION NOTE (daysIntervalBetweenYears.monthFormat):
+# If your language requires a different declension, change this to
 # one of the values specified in dateFormat.properties.
 # In any case, DO NOT TRANSLATE.
-dayIntervalBetweenMonths.monthFormat=nominative
-
-# LOCALIZATION NOTE (dayIntervalBetweenYears):
-# used for display of intervals in the form 'December 29, 2008 - January 4, 2009'
-#    %1$S will be replaced with name of the month of the start date
-#    %2$S will be replaced with the day-index of the start date
-#    %3$S will be replaced with the year of the start date
-#    %4$S will be replaced with name of the month of the end date
-#    %5$S will be replaced with the day-index of the end date
-#    %6$S will be replaced with the year of the end date
-dayIntervalBetweenYears=%1$S %2$S, %3$S – %4$S %5$S, %6$S
-
-# LOCALIZATION NOTE (dayIntervalBetweenYears.monthFormat):
-# If your language requires a different declension, change this to 
-# one of the values specified in dateFormat.properties.
-# In any case, DO NOT TRANSLATE.
-dayIntervalBetweenYears.monthFormat=nominative
+daysIntervalBetweenYears.monthFormat=nominative
 
 # LOCALIZATION NOTE (datetimeIntervalOnSameDateTime):
 # used for intervals where end is equals to start
 # displayed form is '5 Jan 2006 13:00'
 #    %1$S will be replaced with the date of the start date
 #    %2$S will be replaced with the time of the start date
 datetimeIntervalOnSameDateTime=%1$S %2$S
 
--- a/calendar/locales/en-US/chrome/calendar/dateFormat.properties
+++ b/calendar/locales/en-US/chrome/calendar/dateFormat.properties
@@ -114,13 +114,33 @@ day.24.number=24
 day.25.number=25
 day.26.number=26
 day.27.number=27
 day.28.number=28
 day.29.number=29
 day.30.number=30
 day.31.number=31
 
+# LOCALIZATION NOTE (dayOrdinalSymbol):
+# Allows to insert a string, a character or a symbol after the number of a
+# monthday in order to give it the meaning of ordinal number e.g.  1 -> 1st etc.
+# It's mainly used when formatting dates with both monthday and month name. It
+# affects the following localizable strings that hence must be localized *without*
+# any ordinal symbol for the monthday number:
+#   dayHeaderLabel, monthlyDaysOfNth_day,
+#   yearlyNthOn, daysIntervalBetweenYears,
+#   daysIntervalBetweenMonths, daysIntervalInMonth.
+# Write only a single string if the ordinal symbol is the same for every monthday, otherwise
+# write a sequence of _31_ strings (one for each monthday) separated with commas.
+# If your language doesn't require that in the mentioned strings, leave it empty.
+# e.g.
+# dayOrdinalSymbol=.
+#    -> daysIntervalInMonth: 'March 3. - 9., 2008'
+# dayOrdinalSymbol=st,nd,rd,th,th,th,th,th,th,th,th,th,th,th,th,
+#                  th,th,th,th,th,st,nd,rd,th,th,th,th,th,th,th,st
+#    -> daysIntervalBetweenMonths: 'September 29th - November 1st, 2008'
+dayOrdinalSymbol=
+
 noon=Noon
 midnight=Midnight
 
 AllDay=All Day
 Repeating=(Repeating)