|
|
// define module
|
|
|
var AgeModule = (function () {
|
|
|
return {
|
|
|
age: function(prevdate, now, show_short_version, show_suffix, short_format) {
|
|
|
|
|
|
var prevdate = moment(prevdate);
|
|
|
var now = now || moment().utc();
|
|
|
|
|
|
var show_short_version = show_short_version || false;
|
|
|
var show_suffix = show_suffix || true;
|
|
|
var short_format = short_format || false;
|
|
|
|
|
|
var _get_relative_delta = function(now, prevdate) {
|
|
|
|
|
|
var duration = moment.duration(moment(now).diff(prevdate));
|
|
|
return {
|
|
|
'year': duration.years(),
|
|
|
'month': duration.months(),
|
|
|
'day': duration.days(),
|
|
|
'hour': duration.hours(),
|
|
|
'minute': duration.minutes(),
|
|
|
'second': duration.seconds()
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
var _is_leap_year = function(year){
|
|
|
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
|
|
|
};
|
|
|
|
|
|
var get_month = function(prevdate) {
|
|
|
return prevdate.getMonth()
|
|
|
};
|
|
|
|
|
|
var get_year = function(prevdate) {
|
|
|
return prevdate.getYear()
|
|
|
};
|
|
|
|
|
|
var order = ['year', 'month', 'day', 'hour', 'minute', 'second'];
|
|
|
var deltas = {};
|
|
|
var future = false;
|
|
|
|
|
|
if (prevdate > now) {
|
|
|
var now_old = now;
|
|
|
now = prevdate;
|
|
|
prevdate = now_old;
|
|
|
future = true;
|
|
|
}
|
|
|
if (future) {
|
|
|
// ? remove microseconds, we don't have it in JS
|
|
|
}
|
|
|
|
|
|
// Get date parts deltas
|
|
|
for (part in order) {
|
|
|
var part = order[part];
|
|
|
var rel_delta = _get_relative_delta(now, prevdate);
|
|
|
deltas[part] = rel_delta[part]
|
|
|
}
|
|
|
|
|
|
//# Fix negative offsets (there is 1 second between 10:59:59 and 11:00:00,
|
|
|
//# not 1 hour, -59 minutes and -59 seconds)
|
|
|
var offsets = [[5, 60], [4, 60], [3, 24]];
|
|
|
for (element in offsets) { //# seconds, minutes, hours
|
|
|
var element = offsets[element];
|
|
|
var num = element[0];
|
|
|
var length = element[1];
|
|
|
|
|
|
var part = order[num];
|
|
|
var carry_part = order[num - 1];
|
|
|
|
|
|
if (deltas[part] < 0){
|
|
|
deltas[part] += length;
|
|
|
deltas[carry_part] -= 1
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// # Same thing for days except that the increment depends on the (variable)
|
|
|
// # number of days in the month
|
|
|
var month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
|
if (deltas['day'] < 0) {
|
|
|
if (get_month(prevdate) == 2 && _is_leap_year(get_year(prevdate))) {
|
|
|
deltas['day'] += 29;
|
|
|
} else {
|
|
|
deltas['day'] += month_lengths[get_month(prevdate) - 1];
|
|
|
}
|
|
|
|
|
|
deltas['month'] -= 1
|
|
|
}
|
|
|
|
|
|
if (deltas['month'] < 0) {
|
|
|
deltas['month'] += 12;
|
|
|
deltas['year'] -= 1;
|
|
|
}
|
|
|
|
|
|
//# Format the result
|
|
|
if (short_format) {
|
|
|
var fmt_funcs = {
|
|
|
'year': function(d) {return '{0}y'.format(d)},
|
|
|
'month': function(d) {return '{0}m'.format(d)},
|
|
|
'day': function(d) {return '{0}d'.format(d)},
|
|
|
'hour': function(d) {return '{0}h'.format(d)},
|
|
|
'minute': function(d) {return '{0}min'.format(d)},
|
|
|
'second': function(d) {return '{0}sec'.format(d)}
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
var fmt_funcs = {
|
|
|
'year': function(d) {return _ngettext('{0} year', '{0} years', d).format(d)},
|
|
|
'month': function(d) {return _ngettext('{0} month', '{0} months', d).format(d)},
|
|
|
'day': function(d) {return _ngettext('{0} day', '{0} days', d).format(d)},
|
|
|
'hour': function(d) {return _ngettext('{0} hour', '{0} hours', d).format(d)},
|
|
|
'minute': function(d) {return _ngettext('{0} min', '{0} min', d).format(d)},
|
|
|
'second': function(d) {return _ngettext('{0} sec', '{0} sec', d).format(d)}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
var i = 0;
|
|
|
for (part in order){
|
|
|
var part = order[part];
|
|
|
var value = deltas[part];
|
|
|
if (value !== 0) {
|
|
|
|
|
|
if (i < 5) {
|
|
|
var sub_part = order[i + 1];
|
|
|
var sub_value = deltas[sub_part]
|
|
|
} else {
|
|
|
var sub_value = 0
|
|
|
}
|
|
|
if (sub_value == 0 || show_short_version) {
|
|
|
var _val = fmt_funcs[part](value);
|
|
|
if (future) {
|
|
|
if (show_suffix) {
|
|
|
return _gettext('in {0}').format(_val)
|
|
|
} else {
|
|
|
return _val
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else {
|
|
|
if (show_suffix) {
|
|
|
return _gettext('{0} ago').format(_val)
|
|
|
} else {
|
|
|
return _val
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
var val = fmt_funcs[part](value);
|
|
|
var val_detail = fmt_funcs[sub_part](sub_value);
|
|
|
if (short_format) {
|
|
|
var datetime_tmpl = '{0}, {1}';
|
|
|
if (show_suffix) {
|
|
|
datetime_tmpl = _gettext('{0}, {1} ago');
|
|
|
if (future) {
|
|
|
datetime_tmpl = _gettext('in {0}, {1}');
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
var datetime_tmpl = _gettext('{0} and {1}');
|
|
|
if (show_suffix) {
|
|
|
datetime_tmpl = _gettext('{0} and {1} ago');
|
|
|
if (future) {
|
|
|
datetime_tmpl = _gettext('in {0} and {1}')
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return datetime_tmpl.format(val, val_detail)
|
|
|
}
|
|
|
i += 1;
|
|
|
}
|
|
|
|
|
|
return _gettext('just now')
|
|
|
|
|
|
},
|
|
|
createTimeComponent: function(dateTime, text) {
|
|
|
return '<time class="timeago tooltip" title="{1}" datetime="{0}+0000">{1}</time>'.format(dateTime, text);
|
|
|
}
|
|
|
}
|
|
|
})();
|
|
|
|
|
|
|
|
|
jQuery.timeago.settings.localeTitle = false;
|
|
|
|
|
|
// auto refresh the components every Ns
|
|
|
jQuery.timeago.settings.refreshMillis = templateContext.timeago.refresh_time;
|
|
|
|
|
|
// Display original dates older than N days
|
|
|
jQuery.timeago.settings.cutoff = templateContext.timeago.cutoff_limit;
|
|
|
|