diff --git a/toolkit/mozapps/downloads/DownloadUtils.jsm b/toolkit/mozapps/downloads/DownloadUtils.jsm index 52c0f5860229..39d925872bac 100644 --- a/toolkit/mozapps/downloads/DownloadUtils.jsm +++ b/toolkit/mozapps/downloads/DownloadUtils.jsm @@ -53,6 +53,9 @@ var EXPORTED_SYMBOLS = [ "DownloadUtils" ]; * [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) * @@ -93,6 +96,8 @@ let kStrings = { timeLeftDouble: "timeLeftDouble", timeFewSeconds: "timeFewSeconds", timeUnknown: "timeUnknown", + monthDate: "monthDate", + yesterday: "yesterday", doneScheme: "doneScheme", doneFileScheme: "doneFileScheme", units: ["bytes", "kilobyte", "megabyte", "gigabyte"], @@ -320,6 +325,71 @@ let DownloadUtils = { 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 diff --git a/toolkit/mozapps/downloads/content/downloads.js b/toolkit/mozapps/downloads/content/downloads.js index 9ddb998f4de9..79bf050ce591 100644 --- a/toolkit/mozapps/downloads/content/downloads.js +++ b/toolkit/mozapps/downloads/content/downloads.js @@ -111,8 +111,6 @@ let gStr = { stateBlockedParentalControls: "stateBlocked", stateBlockedPolicy: "stateBlockedPolicy", stateDirty: "stateDirty", - yesterday: "yesterday", - monthDate: "monthDate", downloadsTitleFiles: "downloadsTitleFiles", downloadsTitlePercent: "downloadsTitlePercent", fileExecutableSecurityWarningTitle: "fileExecutableSecurityWarningTitle", @@ -1052,51 +1050,10 @@ function updateTime(aItem) 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); } /** diff --git a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js index 6543dc8a9e25..10a4836f4861 100644 --- a/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js +++ b/toolkit/mozapps/downloads/tests/unit/test_DownloadUtils.js @@ -96,6 +96,47 @@ function testURI(aURI, aDisp, aHost) 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"); @@ -163,4 +204,6 @@ function run_test() 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(); }