aboutsummaryrefslogtreecommitdiff
path: root/underlays/javascript/ikiwiki/relativedate.js
blob: 2a270d627abd45c706d9de78224f681dc96fd7d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Causes html elements in the 'relativedate' class to be displayed
// as relative dates. The date is parsed from the title attribute, or from
// the element content.

var dateElements;

hook("onload", getDates);

function getDates() {
	dateElements = getElementsByClass('relativedate');
	for (var i = 0; i < dateElements.length; i++) {
		var elt = dateElements[i];
		var title = elt.attributes.title;
		var d = new Date(title ? title.value : elt.innerHTML);
		if (! isNaN(d)) {
			dateElements[i].date=d;
			elt.title=elt.innerHTML;
		}
	}

	showDates();
}

function showDates() {
	for (var i = 0; i < dateElements.length; i++) {
		var elt = dateElements[i];
		var d = elt.date;
		if (! isNaN(d)) {
			elt.innerHTML=relativeDate(d);
		}
	}
	setTimeout(showDates,30000); // keep updating every 30s
}

var timeUnits = [
	{ unit: 'year',		seconds: 60 * 60 * 24 * 364 },
	{ unit: 'month',	seconds: 60 * 60 * 24 * 30 },
	{ unit: 'day',		seconds: 60 * 60 * 24 },
	{ unit: 'hour',		seconds: 60 * 60 },
	{ unit: 'minute',	seconds: 60 },
];

function relativeDate(date) {
	var now = new Date();
	var offset = date.getTime() - now.getTime();
	var seconds = Math.round(Math.abs(offset) / 1000);

	// hack to avoid reading just in the future if there is a minor
	// amount of clock slip
	if (offset >= 0 && seconds < 30 * 60 * 60) {
		return "just now";
	}

	var ret = "";
	var shown = 0;
	for (i = 0; i < timeUnits.length; i++) {
		if (seconds >= timeUnits[i].seconds) {
			var num = Math.floor(seconds / timeUnits[i].seconds);
			seconds -= num * timeUnits[i].seconds;
			if (ret)
				ret += "and ";
			ret += num + " " + timeUnits[i].unit + (num > 1 ? "s" : "") + " ";

			if (++shown == 2)
				break;
		}
		else if (shown)
			break;
	}

	if (! ret)
		ret = "less than a minute "

	return ret + (offset < 0 ? "ago" : "from now");
}