Bug 653261 - Add a function to format the date and time displayed in the Download Manager. r=sdwilsh sr=mconnor
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Wed, 27 Jul 2011 13:08:24 +0200
changeset 73803 69913a1505dfca87506c910636a98a749d294d90
parent 73802 e6ce4fc82ffc96d742afcb7aa28869da98dd5b14
child 73804 6c9c2e013decc70308333fae23caed5a8ead945f
push id313
push usereakhgari@mozilla.com
push dateTue, 16 Aug 2011 19:58:41 +0000
treeherdermozilla-aurora@ef9d1c90dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssdwilsh, mconnor
bugs653261
milestone8.0a1
Bug 653261 - Add a function to format the date and time displayed in the Download Manager. r=sdwilsh sr=mconnor
toolkit/mozapps/downloads/DownloadUtils.jsm
toolkit/mozapps/downloads/content/downloads.js
toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
--- a/toolkit/mozapps/downloads/DownloadUtils.jsm
+++ b/toolkit/mozapps/downloads/DownloadUtils.jsm
@@ -48,16 +48,19 @@ var EXPORTED_SYMBOLS = [ "DownloadUtils"
  *                   [optional] double aSpeed, [optional] double aLastSec)
  *
  * string progress
  * getTransferTotal(int aCurrBytes, [optional] int aMaxBytes)
  *
  * [string timeLeft, double newLast]
  * getTimeLeft(double aSeconds, [optional] double aLastSec)
  *
+ * [string dateCompact, string dateComplete]
+ * getReadableDates(Date aDate, [optional] Date aNow)
+ *
  * [string displayHost, string fullHost]
  * getURIHost(string aURIString)
  *
  * [string convertedBytes, string units]
  * convertByteUnits(int aBytes)
  *
  * [int time, string units, int subTime, string subUnits]
  * convertTimeUnits(double aSecs)
@@ -88,16 +91,18 @@ let kStrings = {
   transferSameUnits: "transferSameUnits",
   transferDiffUnits: "transferDiffUnits",
   transferNoTotal: "transferNoTotal",
   timePair: "timePair",
   timeLeftSingle: "timeLeftSingle",
   timeLeftDouble: "timeLeftDouble",
   timeFewSeconds: "timeFewSeconds",
   timeUnknown: "timeUnknown",
+  monthDate: "monthDate",
+  yesterday: "yesterday",
   doneScheme: "doneScheme",
   doneFileScheme: "doneFileScheme",
   units: ["bytes", "kilobyte", "megabyte", "gigabyte"],
   // Update timeSize in convertTimeUnits if changing the length of this array
   timeUnits: ["seconds", "minutes", "hours", "days"],
 };
 
 // This object will lazily load the strings defined in kStrings
@@ -316,16 +321,81 @@ let DownloadUtils = {
         timeLeft = replaceInsert(timeLeft, 2, pair2);
       }
     }
 
     return [timeLeft, aSeconds];
   },
 
   /**
+   * Converts a Date object to two readable formats, one compact, one complete.
+   * The compact format is relative to the current date, and is not an accurate
+   * representation. For example, only the time is displayed for today. The
+   * complete format always includes both the date and the time, excluding the
+   * seconds, and is often shown when hovering the cursor over the compact
+   * representation.
+   *
+   * @param aDate
+   *        Date object representing the date and time to format. It is assumed
+   *        that this value represents a past date.
+   * @param [optional] aNow
+   *        Date object representing the current date and time. The real date
+   *        and time of invocation is used if this parameter is omitted.
+   * @return A pair: [compact text, complete text]
+   */
+  getReadableDates: function DU_getReadableDates(aDate, aNow)
+  {
+    if (!aNow) {
+      aNow = new Date();
+    }
+
+    let dts = Cc["@mozilla.org/intl/scriptabledateformat;1"]
+              .getService(Ci.nsIScriptableDateFormat);
+
+    // Figure out when today begins
+    let today = new Date(aNow.getFullYear(), aNow.getMonth(), aNow.getDate());
+
+    // Figure out if the time is from today, yesterday, this week, etc.
+    let dateTimeCompact;
+    if (aDate >= today) {
+      // After today started, show the time
+      dateTimeCompact = dts.FormatTime("",
+                                       dts.timeFormatNoSeconds,
+                                       aDate.getHours(),
+                                       aDate.getMinutes(),
+                                       0);
+    } else if (today - aDate < (24 * 60 * 60 * 1000)) {
+      // After yesterday started, show yesterday
+      dateTimeCompact = gStr.yesterday;
+    } else if (today - aDate < (6 * 24 * 60 * 60 * 1000)) {
+      // After last week started, show day of week
+      dateTimeCompact = aDate.toLocaleFormat("%A");
+    } else {
+      // Show month/day
+      let month = aDate.toLocaleFormat("%B");
+      // Remove leading 0 by converting the date string to a number
+      let date = Number(aDate.toLocaleFormat("%d"));
+      dateTimeCompact = replaceInsert(gStr.monthDate, 1, month);
+      dateTimeCompact = replaceInsert(dateTimeCompact, 2, date);
+    }
+
+    let dateTimeFull = dts.FormatDateTime("",
+                                          dts.dateFormatLong,
+                                          dts.timeFormatNoSeconds,
+                                          aDate.getFullYear(),
+                                          aDate.getMonth() + 1,
+                                          aDate.getDate(),
+                                          aDate.getHours(),
+                                          aDate.getMinutes(),
+                                          0);
+
+    return [dateTimeCompact, dateTimeFull];
+  },
+
+  /**
    * Get the appropriate display host string for a URI string depending on if
    * the URI has an eTLD + 1, is an IP address, a local file, or other protocol
    *
    * @param aURIString
    *        The URI string to try getting an eTLD + 1, etc.
    * @return A pair: [display host for the URI string, full host name]
    */
   getURIHost: function DU_getURIHost(aURIString)
--- a/toolkit/mozapps/downloads/content/downloads.js
+++ b/toolkit/mozapps/downloads/content/downloads.js
@@ -106,18 +106,16 @@ let gStr = {
   doneStatus: "doneStatus",
   doneSize: "doneSize",
   doneSizeUnknown: "doneSizeUnknown",
   stateFailed: "stateFailed",
   stateCanceled: "stateCanceled",
   stateBlockedParentalControls: "stateBlocked",
   stateBlockedPolicy: "stateBlockedPolicy",
   stateDirty: "stateDirty",
-  yesterday: "yesterday",
-  monthDate: "monthDate",
   downloadsTitleFiles: "downloadsTitleFiles",
   downloadsTitlePercent: "downloadsTitlePercent",
   fileExecutableSecurityWarningTitle: "fileExecutableSecurityWarningTitle",
   fileExecutableSecurityWarningDontAsk: "fileExecutableSecurityWarningDontAsk"
 };
 
 // The statement to query for downloads that are active or match the search
 let gStmt = null;
@@ -1047,61 +1045,20 @@ function updateStatus(aItem, aDownload) 
  *        The richlistitem representing a download in the UI
  */
 function updateTime(aItem)
 {
   // Don't bother updating for things that aren't finished
   if (aItem.inProgress)
     return;
 
-  let dts = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-            getService(Ci.nsIScriptableDateFormat);
-
-  // Figure out when today begins
-  let now = new Date();
-  let today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
-
-  // Get the end time to display
   let end = new Date(parseInt(aItem.getAttribute("endTime")));
-
-  // Figure out if the end time is from today, yesterday, this week, etc.
-  let dateTime;
-  if (end >= today) {
-    // Download finished after today started, show the time
-    dateTime = dts.FormatTime("", dts.timeFormatNoSeconds,
-                              end.getHours(), end.getMinutes(), 0);
-  } else if (today - end < (24 * 60 * 60 * 1000)) {
-    // Download finished after yesterday started, show yesterday
-    dateTime = gStr.yesterday;
-  } else if (today - end < (6 * 24 * 60 * 60 * 1000)) {
-    // Download finished after last week started, show day of week
-    dateTime = end.toLocaleFormat("%A");
-  } else {
-    // Download must have been from some time ago.. show month/day
-    let month = end.toLocaleFormat("%B");
-    // Remove leading 0 by converting the date string to a number
-    let date = Number(end.toLocaleFormat("%d"));
-    dateTime = replaceInsert(gStr.monthDate, 1, month);
-    dateTime = replaceInsert(dateTime, 2, date);
-  }
-
-  aItem.setAttribute("dateTime", dateTime);
-
-  // Set the tooltip to be the full date and time
-  let dateTimeTip = dts.FormatDateTime("",
-                                       dts.dateFormatLong,
-                                       dts.timeFormatNoSeconds,
-                                       end.getFullYear(),
-                                       end.getMonth() + 1,
-                                       end.getDate(),
-                                       end.getHours(),
-                                       end.getMinutes(),
-                                       0); 
-
-  aItem.setAttribute("dateTimeTip", dateTimeTip);
+  let [dateCompact, dateComplete] = DownloadUtils.getReadableDates(end);
+  aItem.setAttribute("dateTime", dateCompact);
+  aItem.setAttribute("dateTimeTip", dateComplete);
 }
 
 /**
  * Helper function to replace a placeholder string with a real string
  *
  * @param aText
  *        Source text containing placeholder (e.g., #1)
  * @param aIndex
--- a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
+++ b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js
@@ -91,16 +91,57 @@ function testURI(aURI, aDisp, aHost)
 
   let [disp, host] = DownloadUtils.getURIHost(aURI);
 
   // Make sure we have the right display host and full host
   do_check_eq(disp, aDisp);
   do_check_eq(host, aHost);
 }
 
+
+function testGetReadableDates(aDate, aCompactValue)
+{
+  const now = new Date(2000, 11, 31, 11, 59, 59);
+
+  let [dateCompact] = DownloadUtils.getReadableDates(aDate, now);
+  do_check_eq(dateCompact, aCompactValue);
+}
+
+function testAllGetReadableDates()
+{
+  // This test cannot depend on the current date and time, or the date format.
+  // It depends on being run with the English localization, however.
+  const today_11_30     = new Date(2000, 11, 31, 11, 30, 15);
+  const today_12_30     = new Date(2000, 11, 31, 12, 30, 15);
+  const yesterday_11_30 = new Date(2000, 11, 30, 11, 30, 15);
+  const yesterday_12_30 = new Date(2000, 11, 30, 12, 30, 15);
+  const twodaysago      = new Date(2000, 11, 29, 11, 30, 15);
+  const sixdaysago      = new Date(2000, 11, 25, 11, 30, 15);
+  const sevendaysago    = new Date(2000, 11, 24, 11, 30, 15);
+
+  let dts = Components.classes["@mozilla.org/intl/scriptabledateformat;1"].
+            getService(Components.interfaces.nsIScriptableDateFormat);
+
+  testGetReadableDates(today_11_30, dts.FormatTime("", dts.timeFormatNoSeconds,
+                                                   11, 30, 0));
+  testGetReadableDates(today_12_30, dts.FormatTime("", dts.timeFormatNoSeconds,
+                                                   12, 30, 0));
+  testGetReadableDates(yesterday_11_30, "Yesterday");
+  testGetReadableDates(yesterday_12_30, "Yesterday");
+  testGetReadableDates(twodaysago, twodaysago.toLocaleFormat("%A"));
+  testGetReadableDates(sixdaysago, sixdaysago.toLocaleFormat("%A"));
+  testGetReadableDates(sevendaysago, sevendaysago.toLocaleFormat("%B") + " " +
+                                     sevendaysago.toLocaleFormat("%d"));
+
+  let [, dateTimeFull] = DownloadUtils.getReadableDates(today_11_30);
+  do_check_eq(dateTimeFull, dts.FormatDateTime("", dts.dateFormatLong,
+                                                   dts.timeFormatNoSeconds,
+                                                   2000, 12, 31, 11, 30, 0));
+}
+
 function run_test()
 {
   testConvertByteUnits(-1, "-1", "bytes");
   testConvertByteUnits(1, _("1"), "bytes");
   testConvertByteUnits(42, _("42"), "bytes");
   testConvertByteUnits(123, _("123"), "bytes");
   testConvertByteUnits(1024, _("1.0"), "KB");
   testConvertByteUnits(8888, _("8.7"), "KB");
@@ -158,9 +199,11 @@ function run_test()
 
   testURI("http://www.mozilla.org/", "mozilla.org", "www.mozilla.org");
   testURI("http://www.city.mikasa.hokkaido.jp/", "city.mikasa.hokkaido.jp", "www.city.mikasa.hokkaido.jp");
   testURI("data:text/html,Hello World", "data resource", "data resource");
   testURI("jar:http://www.mozilla.com/file!/magic", "mozilla.com", "www.mozilla.com");
   testURI("file:///C:/Cool/Stuff/", "local file", "local file");
   testURI("moz-icon:file:///test.extension", "moz-icon resource", "moz-icon resource");
   testURI("about:config", "about resource", "about resource");
+
+  testAllGetReadableDates();
 }