タイムスタンプ (Twitter API など) をユーザーフレンドリーな相対時間 (2 秒前、1 週間前など) に変換するための素敵な JS スニペットを探しています。
お気に入りの方法を共有したい人はいますか (できればプラグインを使用しないでください)。
タイムスタンプ (Twitter API など) をユーザーフレンドリーな相対時間 (2 秒前、1 週間前など) に変換するための素敵な JS スニペットを探しています。
お気に入りの方法を共有したい人はいますか (できればプラグインを使用しないでください)。
精度をあまり気にしなければ簡単です。些細な方法の何が問題なのですか?
function timeDifference(current, previous) {
var msPerMinute = 60 * 1000;
var msPerHour = msPerMinute * 60;
var msPerDay = msPerHour * 24;
var msPerMonth = msPerDay * 30;
var msPerYear = msPerDay * 365;
var elapsed = current - previous;
if (elapsed < msPerMinute) {
return Math.round(elapsed/1000) + ' seconds ago';
}
else if (elapsed < msPerHour) {
return Math.round(elapsed/msPerMinute) + ' minutes ago';
}
else if (elapsed < msPerDay ) {
return Math.round(elapsed/msPerHour ) + ' hours ago';
}
else if (elapsed < msPerMonth) {
return 'approximately ' + Math.round(elapsed/msPerDay) + ' days ago';
}
else if (elapsed < msPerYear) {
return 'approximately ' + Math.round(elapsed/msPerMonth) + ' months ago';
}
else {
return 'approximately ' + Math.round(elapsed/msPerYear ) + ' years ago';
}
}
ここでの作業例。
気になる場合は、特異値をより適切に処理するために (たとえば1 day
、 の代わりに1 days
) 調整することをお勧めします。
これは、プラグインを使用しない場合の twitter 時間前の正確な模倣です。
function timeSince(timeStamp) {
var now = new Date(),
secondsPast = (now.getTime() - timeStamp) / 1000;
if (secondsPast < 60) {
return parseInt(secondsPast) + 's';
}
if (secondsPast < 3600) {
return parseInt(secondsPast / 60) + 'm';
}
if (secondsPast <= 86400) {
return parseInt(secondsPast / 3600) + 'h';
}
if (secondsPast > 86400) {
day = timeStamp.getDate();
month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ", "");
year = timeStamp.getFullYear() == now.getFullYear() ? "" : " " + timeStamp.getFullYear();
return day + " " + month + year;
}
}
const currentTimeStamp = new Date().getTime();
console.log(timeSince(currentTimeStamp));
要点https://gist.github.com/timuric/11386129
フィドルhttp://jsfiddle.net/qE8Lu/1/
それが役に立てば幸い。
Web API RelativeTimeFormatを使用した @vsync と @kigiri アプローチの Typescript 実装の組み合わせ。
const units: {unit: Intl.RelativeTimeFormatUnit; ms: number}[] = [
{unit: "year", ms: 31536000000},
{unit: "month", ms: 2628000000},
{unit: "day", ms: 86400000},
{unit: "hour", ms: 3600000},
{unit: "minute", ms: 60000},
{unit: "second", ms: 1000},
];
const rtf = new Intl.RelativeTimeFormat("en", {numeric: "auto"});
/**
* Get language-sensitive relative time message from Dates.
* @param relative - the relative dateTime, generally is in the past or future
* @param pivot - the dateTime of reference, generally is the current time
*/
export function relativeTimeFromDates(relative: Date | null, pivot: Date = new Date()): string {
if (!relative) return "";
const elapsed = relative.getTime() - pivot.getTime();
return relativeTimeFromElapsed(elapsed);
}
/**
* Get language-sensitive relative time message from elapsed time.
* @param elapsed - the elapsed time in milliseconds
*/
export function relativeTimeFromElapsed(elapsed: number): string {
for (const {unit, ms} of units) {
if (Math.abs(elapsed) >= ms || unit === "second") {
return rtf.format(Math.round(elapsed / ms), unit);
}
}
return "";
}
興味のある人のために、これを行うために Handlebars ヘルパーを作成しました。使用法:
{{#beautify_date}}
{{timestamp_ms}}
{{/beautify_date}}
ヘルパー:
Handlebars.registerHelper('beautify_date', function(options) {
var timeAgo = new Date(parseInt(options.fn(this)));
if (Object.prototype.toString.call(timeAgo) === "[object Date]") {
if (isNaN(timeAgo.getTime())) {
return 'Not Valid';
} else {
var seconds = Math.floor((new Date() - timeAgo) / 1000),
intervals = [
Math.floor(seconds / 31536000),
Math.floor(seconds / 2592000),
Math.floor(seconds / 86400),
Math.floor(seconds / 3600),
Math.floor(seconds / 60)
],
times = [
'year',
'month',
'day',
'hour',
'minute'
];
var key;
for(key in intervals) {
if (intervals[key] > 1)
return intervals[key] + ' ' + times[key] + 's ago';
else if (intervals[key] === 1)
return intervals[key] + ' ' + times[key] + ' ago';
}
return Math.floor(seconds) + ' seconds ago';
}
} else {
return 'Not Valid';
}
});