2 * Transforms <time> elements to display the elapsed time relative to the current time.
4 * @author Alexander Ebert
5 * @copyright 2001-2018 WoltLab GmbH
6 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
7 * @module WoltLabSuite/Core/Date/Time/Relative
9 define(['Dom/ChangeListener', 'Language', 'WoltLabSuite/Core/Date/Util', 'WoltLabSuite/Core/Timer/Repeating'], function(DomChangeListener
, Language
, DateUtil
, Repeating
) {
12 var _elements
= elByTag('time');
14 var _isPending
= false;
18 * @exports WoltLabSuite/Core/Date/Time/Relative
22 * Transforms <time> elements on init and binds event listeners.
25 new Repeating(this._refresh
.bind(this), 60000);
27 DomChangeListener
.add('WoltLabSuite/Core/Date/Time/Relative', this._refresh
.bind(this));
29 document
.addEventListener('visibilitychange', this._onVisibilityChange
.bind(this));
32 _onVisibilityChange: function () {
33 if (document
.hidden
) {
40 // force immediate refresh
48 _refresh: function() {
49 // activity is suspended while the tab is hidden, but force an
50 // immediate refresh once the page is active again
52 if (!_isPending
) _isPending
= true;
56 var date
= new Date();
57 var timestamp
= (date
.getTime() - date
.getMilliseconds()) / 1000;
58 if (_offset
=== null) _offset
= timestamp
- window
.TIME_NOW
;
60 for (var i
= 0, length
= _elements
.length
; i
< length
; i
++) {
61 var element
= _elements
[i
];
63 if (!element
.classList
.contains('datetime') || elData(element
, 'is-future-date')) continue;
65 var elTimestamp
= ~~elData(element
, 'timestamp') + _offset
;
66 var elDate
= elData(element
, 'date');
67 var elTime
= elData(element
, 'time');
68 var elOffset
= elData(element
, 'offset');
70 if (!elAttr(element
, 'title')) {
71 elAttr(element
, 'title', Language
.get('wcf.date.dateTimeFormat').replace(/%date%/, elDate
).replace(/%time%/, elTime
));
74 // timestamp is less than 60 seconds ago
75 if (elTimestamp
>= timestamp
|| timestamp
< (elTimestamp
+ 60)) {
76 element
.textContent
= Language
.get('wcf.date.relative.now');
78 // timestamp is less than 60 minutes ago (display 1 hour ago rather than 60 minutes ago)
79 else if (timestamp
< (elTimestamp
+ 3540)) {
80 var minutes
= Math
.max(Math
.round((timestamp
- elTimestamp
) / 60), 1);
81 element
.textContent
= Language
.get('wcf.date.relative.minutes', { minutes
: minutes
});
83 // timestamp is less than 24 hours ago
84 else if (timestamp
< (elTimestamp
+ 86400)) {
85 var hours
= Math
.round((timestamp
- elTimestamp
) / 3600);
86 element
.textContent
= Language
.get('wcf.date.relative.hours', { hours
: hours
});
88 // timestamp is less than 6 days ago
89 else if (timestamp
< (elTimestamp
+ 518400)) {
90 var midnight
= new Date(date
.getFullYear(), date
.getMonth(), date
.getDate());
91 var days
= Math
.ceil((midnight
/ 1000 - elTimestamp
) / 86400);
94 var dateObj
= DateUtil
.getTimezoneDate((elTimestamp
* 1000), elOffset
* 1000);
95 var dow
= dateObj
.getDay();
96 var day
= Language
.get('__days')[dow
];
98 element
.textContent
= Language
.get('wcf.date.relative.pastDays', { days
: days
, day
: day
, time
: elTime
});
100 // timestamp is between ~700 million years BC and last week
102 element
.textContent
= Language
.get('wcf.date.shortDateTimeFormat').replace(/%date%/, elDate
).replace(/%time%/, elTime
);