原文地址:《Vue系列》timeago.js将时间戳转换成“几天前”“几分钟前”等格式 | 理木客www.limuke.top
![c60a4b08235c13326d69469cbce031fe.png](https://i-blog.csdnimg.cn/blog_migrate/bb35260e09d0928ae360d50c85deaade.jpeg)
1、引入timeago.js>1.引入timeago.js
/**
* Copyright (c) 2016 hustcc
* License: MIT
* Version: v3.0.2
* https://github.com/hustcc/timeago.js
**/
/* jshint expr: true */
!function (root, factory) {
if (typeof module === 'object' && module.exports) {
module.exports = factory(root); // nodejs support
module.exports['default'] = module.exports; // es6 support
}
else
root.timeago = factory(root);
}(typeof window !== 'undefined' ? window : this,
function () {
var indexMapEn = 'second_minute_hour_day_week_month_year'.split('_'),
indexMapZh = '秒_分钟_小时_天_周_月_年'.split('_'),
// build-in locales: en & zh_CN
locales = {
'en': function(number, index) {
if (index === 0) return ['just now', 'right now'];
var unit = indexMapEn[parseInt(index / 2)];
if (number > 1) unit += 's';
return [number + ' ' + unit + ' ago', 'in ' + number + ' ' + unit];
},
'zh_CN': function(number, index) {
if (index === 0) return ['刚刚', '片刻后'];
var unit = indexMapZh[parseInt(index / 2)];
return [number + unit + '前', number + unit + '后'];
}
},
// second, minute, hour, day, week, month, year(365 days)
SEC_ARRAY = [60, 60, 24, 7, 365/7/12, 12],
SEC_ARRAY_LEN = 6,
// ATTR_DATETIME = 'datetime',
ATTR_DATA_TID = 'data-tid',
timers = {}; // real-time render timers
// format Date / string / timestamp to Date instance.
function toDate(input) {
if (input instanceof Date) return input;
if (!isNaN(input)) return new Date(toInt(input));
if (/^d+$/.test(input)) return new Date(toInt(input));
input = (input || '').trim().replace(/.d+/, '') // remove milliseconds
.replace(/-/, '/').replace(/-/, '/')
.replace(/(d)T(d)/, '$1 $2').replace(/Z/, ' UTC') // 2017-2-5T3:57:52Z -> 2017-2-5 3:57:52UTC
.replace(/([+-]dd):?(dd)/, ' $1$2'); // -04:00 -> -0400
return new Date(input);
}
// change f into int, remove decimal. Just for code compression
function toInt(f) {
return parseInt(f);
}
// format the diff second to *** time ago, with setting locale
function formatDiff(diff, locale, defaultLocale) {
// if locale is not exist, use defaultLocale.
// if defaultLocale is not exist, use build-in `en`.
// be sure of no error when locale is not exist.
locale = locales[locale] ? locale : (locales[defaultLocale] ? defaultLocale : 'en');
// if (! locales[locale]) locale = defaultLocale;
var i = 0,
agoin = diff < 0 ? 1 : 0, // timein or timeago
total_sec = diff = Math.abs(diff);
for (; diff >= SEC_ARRAY[i] && i < SEC_ARRAY_LEN; i++) {
diff /= SEC_ARRAY[i];
}
diff = toInt(diff);
i *= 2;
if (diff > (i === 0 ? 9 : 1)) i += 1;
return locales[locale](diff, i, total_sec)[agoin].replace('%s', diff);
}
// calculate the diff second between date to be formated an now date.
function diffSec(date, nowDate) {
nowDate = nowDate ? toDate(nowDate) : new Date();
return (nowDate - toDate(date)) / 1000;
}
/**
* nextInterval: calculate the next interval time.
* - diff: the diff sec between now and date to be formated.
*
* What's the meaning?
* diff = 61 then return 59
* diff = 3601 (an hour + 1 second), then return 3599
* make the interval with high performace.
**/
function nextInterval(diff) {
var rst = 1, i = 0, d = Math.abs(diff);
for (; diff >= SEC_ARRAY[i] && i < SEC_ARRAY_LEN; i++) {
diff /= SEC_ARRAY[i];
rst *= SEC_ARRAY[i];
}
// return leftSec(d, rst);
d = d % rst;
d = d ? rst - d : rst;
return Math.ceil(d);
}
// get the datetime attribute, `data-timeagp` / `datetime` are supported.
function getDateAttr(node) {
return getAttr(node, 'data-timeago') || getAttr(node, 'datetime');
}
// get the node attribute, native DOM and jquery supported.
function getAttr(node, name) {
if(node.getAttribute) return node.getAttribute(name); // native
if(node.attr) return node.attr(name); // jquery
}
// set the node attribute, native DOM and jquery supported.
function setTidAttr(node, val) {
if(node.setAttribute) return node.setAttribute(ATTR_DATA_TID, val); // native
if(node.attr) return node.attr(ATTR_DATA_TID, val); // jquery
}
// get the timer id of node.
// remove the function, can save some bytes.
// function getTidFromNode(node) {
// return getAttr(node, ATTR_DATA_TID);
// }
/**
* timeago: the function to get `timeago` instance.
* - nowDate: the relative date, default is new Date().
* - defaultLocale: the default locale, default is en. if your set it, then the `locale` parameter of format is not needed of you.
*
* How to use it?
* var timeagoLib = require('timeago.js');
* var timeago = timeagoLib(); // all use default.
* var timeago = timeagoLib('2016-09-10'); // the relative date is 2016-09-10, so the 2016-09-11 will be 1 day ago.
* var timeago = timeagoLib(null, 'zh_CN'); // set default locale is `zh_CN`.
* var timeago = timeagoLib('2016-09-10', 'zh_CN'); // the relative date is 2016-09-10, and locale is zh_CN, so the 2016-09-11 will be 1天前.
**/
function Timeago(nowDate, defaultLocale) {
this.nowDate = nowDate;
// if do not set the defaultLocale, set it with `en`
this.defaultLocale = defaultLocale || 'en'; // use default build-in locale
// for dev test
// this.nextInterval = nextInterval;
}
// what the timer will do
Timeago.prototype.doRender = function(node, date, locale) {
var diff = diffSec(date, this.nowDate),
self = this,
tid;
// delete previously assigned timeout's id to node
node.innerHTML = formatDiff(diff, locale, this.defaultLocale);
// waiting %s seconds, do the next render
timers[tid = setTimeout(function() {
self.doRender(node, date, locale);
delete timers[tid];
}, Math.min(nextInterval(diff) * 1000, 0x7FFFFFFF))] = 0; // there is no need to save node in object.
// set attribute date-tid
setTidAttr(node, tid);
};
/**
* format: format the date to *** time ago, with setting or default locale
* - date: the date / string / timestamp to be formated
* - locale: the formated string's locale name, e.g. en / zh_CN
*
* How to use it?
* var timeago = require('timeago.js')();
* timeago.format(new Date(), 'pl'); // Date instance
* timeago.format('2016-09-10', 'fr'); // formated date string
* timeago.format(1473473400269); // timestamp with ms
**/
Timeago.prototype.format = function(date, locale) {
return formatDiff(diffSec(date, this.nowDate), locale, this.defaultLocale);
};
/**
* render: render the DOM real-time.
* - nodes: which nodes will be rendered.
* - locale: the locale name used to format date.
*
* How to use it?
* var timeago = require('timeago.js')();
* // 1. javascript selector
* timeago.render(document.querySelectorAll('.need_to_be_rendered'));
* // 2. use jQuery selector
* timeago.render($('.need_to_be_rendered'), 'pl');
*
* Notice: please be sure the dom has attribute `datetime`.
**/
Timeago.prototype.render = function(nodes, locale) {
if (nodes.length === undefined) nodes = [nodes];
for (var i = 0, len = nodes.length; i < len; i++) {
this.doRender(nodes[i], getDateAttr(nodes[i]), locale); // render item
}
};
/**
* setLocale: set the default locale name.
*
* How to use it?
* var timeago = require('timeago.js')();
* timeago.setLocale('fr');
**/
Timeago.prototype.setLocale = function(locale) {
this.defaultLocale = locale;
};
/**
* timeago: the function to get `timeago` instance.
* - nowDate: the relative date, default is new Date().
* - defaultLocale: the default locale, default is en. if your set it, then the `locale` parameter of format is not needed of you.
*
* How to use it?
* var timeagoFactory = require('timeago.js');
* var timeago = timeagoFactory(); // all use default.
* var timeago = timeagoFactory('2016-09-10'); // the relative date is 2016-09-10, so the 2016-09-11 will be 1 day ago.
* var timeago = timeagoFactory(null, 'zh_CN'); // set default locale is `zh_CN`.
* var timeago = timeagoFactory('2016-09-10', 'zh_CN'); // the relative date is 2016-09-10, and locale is zh_CN, so the 2016-09-11 will be 1天前.
**/
function timeagoFactory(nowDate, defaultLocale) {
return new Timeago(nowDate, defaultLocale);
}
/**
* register: register a new language locale
* - locale: locale name, e.g. en / zh_CN, notice the standard.
* - localeFunc: the locale process function
*
* How to use it?
* var timeagoFactory = require('timeago.js');
*
* timeagoFactory.register('the locale name', the_locale_func);
* // or
* timeagoFactory.register('pl', require('timeago.js/locales/pl'));
**/
timeagoFactory.register = function(locale, localeFunc) {
locales[locale] = localeFunc;
};
/**
* cancel: cancels one or all the timers which are doing real-time render.
*
* How to use it?
* For canceling all the timers:
* var timeagoFactory = require('timeago.js');
* var timeago = timeagoFactory();
* timeago.render(document.querySelectorAll('.need_to_be_rendered'));
* timeagoFactory.cancel(); // will stop all the timers, stop render in real time.
*
* For canceling single timer on specific node:
* var timeagoFactory = require('timeago.js');
* var timeago = timeagoFactory();
* var nodes = document.querySelectorAll('.need_to_be_rendered');
* timeago.render(nodes);
* timeagoFactory.cancel(nodes[0]); // will clear a timer attached to the first node, stop render in real time.
**/
timeagoFactory.cancel = function(node) {
var tid;
// assigning in if statement to save space
if (node) {
tid = getAttr(node, ATTR_DATA_TID); // get the timer of DOM node(native / jq).
if (tid) {
clearTimeout(tid);
delete timers[tid];
}
} else {
for (tid in timers) clearTimeout(tid);
timers = {};
}
};
return timeagoFactory;
});
2.在vue分过滤器中定义changeTime方法
filters: {
//计算时间,类似于几分钟前,几小时前,几天前等
changeTime(val){
let time = new Date(val); //先将接收到的json格式的日期数据转换成可用的js对象日期
return new timeago().format(time, 'zh_CN'); //转换成类似于几天前的格式
}
}
3.在template中使用,例如:
time是需要转换的时间戳,changeTime是过滤器中定义的方法
<span>{{time | changeTime}}</span>