상대 시간에 대한 Javascript 타임 스탬프 (예 : 2 초 전, 1 주 전 등), 최상의 방법?
타임 스탬프 (예 : 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
) 조정할 수 있습니다 .
다음은 플러그인이없는 트위터 시간의 정확한 모방입니다.
function timeSince(timeStamp) {
var now = new Date(),
secondsPast = (now.getTime() - timeStamp.getTime()) / 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;
}
}
요점 https://gist.github.com/timuric/11386129
바이올린 http://jsfiddle.net/qE8Lu/1/
도움이 되었기를 바랍니다.
Intl.RelativeTimeFormat- 네이티브 API
현재 (12 월 18 일) 3 단계 제안 , 이미 Chrome 71 에서 구현 됨
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
const millisecondsPerDay = 24 * 60 * 60 * 1000;
[
[3.14 , 'second' ],
[-15 , 'minute' ],
[8 , 'hour' ],
[-1 , 'day' ],
[3 , 'week' ],
[-5 , 'month' ],
[2 , 'quarter'],
[-42 , 'year' ],
[(new Date('9/22/2018') - new Date())/millisecondsPerDay,'day']
].forEach(d => console.log( rtf.format(d[0], d[1]) ));
Intl.RelativeTimeFormat 은 V8 v7.1.179 및 Chrome 71 에서 기본적으로 사용할 수 있습니다 . 이 API가 더 널리 사용 가능 해짐 에 따라 Moment.js , Globalize 및 date-fns 와 같은 라이브러리 가 기본 상대 시간 형식 지정 기능을 선호하는 하드 코딩 된 CLDR 데이터베이스에 대한 종속성을 제거하여로드 시간 성능을 개선하고 구문 분석을 수행 할 수 있습니다. -컴파일 시간 성능, 런타임 성능 및 메모리 사용량.
타다! Timeago : http://timeago.yarp.com/
아 잠깐만-플러그인없이? 그렇다면 그 이유는 무엇입니까? 나는 당신이 플러그인 파일을 열고 그것의 내장을 해킹 할 수 있다고 생각한다.
Diego Castillo awnser 와 timeago.js 플러그인 에서 영감을 받아이를 위해 자체 바닐라 플러그인을 작성했습니다.
var timeElement = document.querySelector('time'),
time = new Date(timeElement.getAttribute('datetime'));
timeElement.innerText = TimeAgo.inWords(time.getTime());
var TimeAgo = (function() {
var self = {};
// Public Methods
self.locales = {
prefix: '',
sufix: 'ago',
seconds: 'less than a minute',
minute: 'about a minute',
minutes: '%d minutes',
hour: 'about an hour',
hours: 'about %d hours',
day: 'a day',
days: '%d days',
month: 'about a month',
months: '%d months',
year: 'about a year',
years: '%d years'
};
self.inWords = function(timeAgo) {
var seconds = Math.floor((new Date() - parseInt(timeAgo)) / 1000),
separator = this.locales.separator || ' ',
words = this.locales.prefix + separator,
interval = 0,
intervals = {
year: seconds / 31536000,
month: seconds / 2592000,
day: seconds / 86400,
hour: seconds / 3600,
minute: seconds / 60
};
var distance = this.locales.seconds;
for (var key in intervals) {
interval = Math.floor(intervals[key]);
if (interval > 1) {
distance = this.locales[key + 's'];
break;
} else if (interval === 1) {
distance = this.locales[key];
break;
}
}
distance = distance.replace(/%d/i, interval);
words += distance + separator + this.locales.sufix;
return words.trim();
};
return self;
}());
// USAGE
var timeElement = document.querySelector('time'),
time = new Date(timeElement.getAttribute('datetime'));
timeElement.innerText = TimeAgo.inWords(time.getTime());
<time datetime="2016-06-13"></time>
관심있는 사람을 위해 핸들 바 도우미를 만들었습니다. 용법:
{{#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';
}
});
Datetime 플러그인은 제대로하기가 매우 어렵 기 때문에 존재합니다. 날짜-시간 불일치를 설명하는 이 비디오 는이 문제에 대해 설명합니다 .
플러그인이없는 위의 모든 솔루션은 올바르지 않습니다.
날짜 및 시간 작업의 경우 플러그인을 사용하는 것이 좋습니다 . 이를 처리하는 수백 개의 플러그인 중 Moment.js 를 사용 하고 작업을 수행합니다.
From the twitter API dcumentation we can see their timestamp format:
"created_at":"Wed Aug 27 13:08:45 +0000 2008"
We can parse with it with Moment.js
const postDatetime = moment(
"Wed Aug 27 13:08:45 +0000 2008",
"dddd, MMMM Do, h:mm:ss a, YYYY"
);
const now = moment();
const timeAgo = now.diff(postDatetime, 'seconds');
To specify the preferred time unit for the diff
, we can use the isSame
method. eg:
if (now.isSame(postDatetime, 'day')) {
const timeUnit = 'days';
}
Overall, constructing something like:
`Posted ${timeAgo} ${timeUnit} ago`;
Refer to your plugin's documentation for handling relative time (ie: "How long ago?") calculations.
There is also sugar.js and relative function for this purpose.
relative - Outputs a string in units relative to the current date ("ago" or "from now").
If you need multilingual and don't want to add a big library like moment. intl-relativeformat from yahoo it a nice solution.
var rf = new IntlRelativeFormat('en-US');
var posts = [
{
id : 1,
title: 'Some Blog Post',
date : new Date(1426271670524)
},
{
id : 2,
title: 'Another Blog Post',
date : new Date(1426278870524)
}
];
posts.forEach(function (post) {
console.log(rf.format(post.date));
});
// => "3 hours ago"
// => "1 hour ago"
You can use machinepack-datetime for this purpose. It is easy and clear with its defined API.
tutorialSchema.virtual('createdOn').get(function () {
const DateTime = require('machinepack-datetime');
let timeAgoString = "";
try {
timeAgoString = DateTime.timeFrom({
toWhen: DateTime.parse({
datetime: this.createdAt
}).execSync(),
fromWhen: new Date().getTime()
}).execSync();
} catch(err) {
console.log('error getting createdon', err);
}
return timeAgoString; // a second ago
});
For Moment.js users, it has fromNow() function that returns "x days" or "x hours ago" from current date/time.
moment([2007, 0, 29]).fromNow(); // 4 years ago
moment([2007, 0, 29]).fromNow(true); // 4 years
'UFO ET IT' 카테고리의 다른 글
파이썬에서 리샘플링하지 않고 PDF에서 이미지를 추출 하시겠습니까? (0) | 2020.12.14 |
---|---|
Git 저장소 재 패키지 실패 (0) | 2020.12.14 |
Vim의 명령 줄 모드에서 일반 모드 모션 사용 (0) | 2020.12.14 |
C #에 "잠금 시도, 시간 초과시 건너 뛰기"작업이 있습니까? (0) | 2020.12.14 |
phpmyadmin이 포함 된 PHP 7은 많은 지원 중단 알림을 제공합니다. (0) | 2020.12.13 |