User:Kxx/comments in local time.js
< User:Kxx
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Kxx/comments in local time. |
/*
COMMENTS IN LOCAL TIME
Description: Changes [[Coordinated Universal Time|UTC]]-based times and dates, such as those used in signatures, to be relative to local time.
Documentation: [[Wikipedia:Comments in Local Time]]
Source: [[User:Gary King/comments in local time.js]]
*/
(function(undefined) {
var window = this, document = window.document;
switch (window.mw.config.get('wgCanonicalNamespace')) {
case '':
case 'MediaWiki':
case 'Special':
return;
}
if (window.mw.config.get('wgAction') === 'history')
return;
var addLeadingZero = function(number) {
return number < 10 ? '0' + number : number;
},
convertMonthToNumber = {
January: 0, Jan: 0,
February: 1, Feb: 1,
March: 2, Mar: 2,
April: 3, Apr: 3,
May: 4,
June: 5, Jun: 5,
July: 6, Jul: 6,
August: 7, Aug: 7,
September: 8, Sep: 8,
October: 9, Oct: 9,
November: 10, Nov: 10,
December: 11, Dec: 11
},
convertNumberToMonth = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
Date = window.Date,
Math = window.Math,
parseInt = window.parseInt,
pluralize = function(term, count) {
return count === 1 ? term : term + 's';
},
search = /(\d\d):(\d\d), (\d{1,2}) ([A-Z][a-z]+) (\d{4}) \(UTC\)/g,
today = new Date(new Date().toDateString()),
adjustTime = function(matches) {
// set the date entered
var time = new Date(Date.UTC(parseInt(matches[5]), convertMonthToNumber[matches[4]], parseInt(matches[3]), parseInt(matches[1]), parseInt(matches[2])));
// determine the time offset
var utcOffset = today.getTimezoneOffset() / -60;
utcOffset = utcOffset >= 0 ? '+' + utcOffset : '−' + -utcOffset;
// set the date bits to output
var year = time.getFullYear();
var month = time.getMonth();
var day = time.getDate();
var hour = time.getHours();
var minute = time.getMinutes();
// output am or pm depending on the date
var ampm = hour <= 11 ? ' am' : ' pm';
if (hour > 12)
hour -= 12;
else if (hour === 0)
hour = 12;
// return 'today', 'yesterday' or 'tomorrow' if that is the case
var oldDate = new Date(year, month, day), date;
switch (Math.round((oldDate.getTime() - today.getTime()) / 8.64e7)) {
case -1:
date = 'yesterday';
break;
case 0:
date = 'today';
break;
case 1:
date = 'tomorrow';
break;
default:
var newDate = new Date(today);
// calculate time difference from today
var daysDiff = Math.round((newDate.getTime() - oldDate.getTime()) / 8.64e7);
var differenceWord, last = '';
if (daysDiff >= 0) {
differenceWord = 'ago';
if (daysDiff <= 7)
last = 'last ';
} else {
differenceWord = 'from now';
if (daysDiff > -7)
last = 'this ';
var tmpDate = newDate;
newDate = oldDate;
oldDate = tmpDate;
}
var newYear = newDate.getFullYear(), newMonth = newDate.getMonth(), newDay = newDate.getDate();
var oldTime = oldDate.getTime(), oldYear = oldDate.getFullYear(), oldMonth = oldDate.getMonth();
var yearsAgo = newYear - oldYear;
if (new Date(oldYear, newMonth, newDay).getTime() < oldTime)
--yearsAgo;
var monthsAgo = ((newYear - yearsAgo) * 12 + newMonth) - (oldYear * 12 + oldMonth);
if (new Date(newYear - yearsAgo, newMonth - monthsAgo, newDay).getTime() < oldTime)
--monthsAgo;
var daysAgo = Math.round((new Date(newYear - yearsAgo, newMonth - monthsAgo, newDay).getTime() - oldTime) / 8.64e7);
var descriptiveParts = [];
if (yearsAgo > 0)
descriptiveParts.push(yearsAgo + ' ' + pluralize('year', yearsAgo));
if (monthsAgo > 0)
descriptiveParts.push(monthsAgo + ' ' + pluralize('month', monthsAgo));
if (daysAgo > 0)
descriptiveParts.push(daysAgo + ' ' + pluralize('day', daysAgo));
var descriptiveDifference = ' (' + descriptiveParts.join(', ') + ' ' + differenceWord + ')';
var formattedDate = convertNumberToMonth[month] + ' ' + day + ', ' + year;
var formattedDayOfTheWeek = ', ' + last + dayNames[time.getDay()];
date = formattedDate + formattedDayOfTheWeek + descriptiveDifference;
}
var finalTime = hour + ':' + addLeadingZero(minute) + ampm;
var returnDate = finalTime + ', ' + date + ' (UTC' + utcOffset + ')';
return returnDate;
},
replaceText = function(root) {
var stack = [root], textNodes = [];
do {
for (var child = stack.pop().firstChild; child; child = child.nextSibling)
if (child.nodeType === 1)
stack.push(child);
else if (child.nodeType === 3)
textNodes.push(child);
} while (stack.length !== 0);
for (var i = 0, length = textNodes.length; i < length; ++i) {
var node = textNodes[i], value = node.textContent;
var match = search.exec(value);
if (!match)
continue;
var fragment = document.createDocumentFragment(), lastIndex = 0;
do {
fragment.appendChild(document.createTextNode(value.substring(lastIndex, match.index)));
lastIndex = search.lastIndex;
var span = document.createElement('span');
span.className = 'localcomments';
span.title = match[0];
span.textContent = adjustTime(match);
fragment.appendChild(span);
match = search.exec(value);
} while (match);
fragment.appendChild(document.createTextNode(value.substr(lastIndex)));
node.parentNode.replaceChild(fragment, node);
}
};
var topContainer = document.getElementById('wikiPreview');
if (!topContainer && window.mw.config.get('wgAction') === 'view')
topContainer = document.getElementById('mw-content-text') || document.getElementById('bodyContent');
if (topContainer)
replaceText(topContainer);
})();