Bug 1139167 - Use UTC-base calculations to prevent birthdays in addressbook being off by one day. r=IanN,mconley a=rkent
authorChristian Hoffmann <christian@hoffie.info>
Tue, 14 Apr 2015 18:49:43 +0200
changeset 21991 3ca0490d9fc943c41457301fc443ea3a2963cc7d
parent 21990 034d3c44fa94b2786940fc42b6a1f190f47e5fb8
child 21992 e29397e78a33b465feeb24dded9e189b1f0bac5b
push id1332
push userkent@caspia.com
push dateTue, 14 Apr 2015 22:49:43 +0000
treeherdercomm-beta@e29397e78a33 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersIanN, mconley, rkent
bugs1139167
Bug 1139167 - Use UTC-base calculations to prevent birthdays in addressbook being off by one day. r=IanN,mconley a=rkent
mail/components/addrbook/content/abCardViewOverlay.js
suite/mailnews/addrbook/abCardViewOverlay.js
--- a/mail/components/addrbook/content/abCardViewOverlay.js
+++ b/mail/components/addrbook/content/abCardViewOverlay.js
@@ -289,21 +289,28 @@ function DisplayCardViewPane(realCard)
     var day = card.getProperty("BirthDay", null);
     var month = card.getProperty("BirthMonth", null);
     var year = card.getProperty("BirthYear", null);
     var dateStr;
     if (day > 0 && day < 32 && month > 0 && month < 13) {
       var date = new Date(year, month - 1, day);
       // if the year exists, just use Date.toLocaleString
       if (year) {
-        date.setFullYear(year);
-        dateStr = date.toLocaleDateString();
+        // use UTC-based calculations to avoid off-by-one day
+        // due to time zone/dst discontinuity
+        date = new Date(Date.UTC(year, month - 1, day));
+        date.setUTCFullYear(year); // to handle two-digit years properly
+        dateStr = date.toLocaleDateString([], {timeZone: "UTC"});
       }
       // if the year doesn't exist, display Month DD (ex. January 01)
       else {
+        // toLocaleFormat() seems to have a different implementation than
+        // toLocaleDateString() and returns correct results even when not
+        // passing UTC times; besides, it would not support an options
+        // parameter for {timeZone: "UTC"} anyway.
         dateStr = date.toLocaleFormat(
           gAddressBookBundle.getString("dateFormatMonthDay")
         );
       }
     }
     else if (year)
       dateStr = year;
     visible = cvSetNodeWithLabel(data.cvBirthday, zBirthday, dateStr);
--- a/suite/mailnews/addrbook/abCardViewOverlay.js
+++ b/suite/mailnews/addrbook/abCardViewOverlay.js
@@ -249,22 +249,30 @@ function DisplayCardViewPane(realCard)
     var day = card.getProperty("BirthDay", null);
     var month = card.getProperty("BirthMonth", null);
     var year = card.getProperty("BirthYear", null);
     var dateStr;
     if (day > 0 && day < 32 && month > 0 && month < 13) {
       var date = new Date(year, month - 1, day);
       // if the year exists, just use Date.toLocaleString
       if (year) {
-        date.setFullYear(year);
-        dateStr = date.toLocaleDateString();
+        // use UTC-based calculations to avoid off-by-one day
+        // due to time zone/dst discontinuity
+        date = new Date(Date.UTC(year, month - 1, day));
+        date.setUTCFullYear(year); // to handle two-digit years properly
+        dateStr = date.toLocaleDateString([], {timeZone: "UTC"});
       }
       // if the year doesn't exist, display Month DD (ex. January 1)
-      else
+      else {
+        // toLocaleFormat() seems to have a different implementation than
+        // toLocaleDateString() and returns correct results even when not
+        // passing UTC times; besides, it would not support an options
+        // parameter for {timeZone: "UTC"} anyway.
         dateStr = date.toLocaleFormat(gAddressBookBundle.getString("dateFormatMonthDay"));
+      }
     }
     else if (year)
       dateStr = year;
     visible = cvSetNodeWithLabel(data.cvBirthday, zBirthday, dateStr);
 
 	  visible = cvSetNodeWithLabel(data.cvCustom1, zCustom1, card.getProperty("Custom1")) || visible;
 	  visible = cvSetNodeWithLabel(data.cvCustom2, zCustom2, card.getProperty("Custom2")) || visible;
 	  visible = cvSetNodeWithLabel(data.cvCustom3, zCustom3, card.getProperty("Custom3")) || visible;