UFO ET IT

상대 시간에 대한 Javascript 타임 스탬프 (예 : 2 초 전, 1 주 전 등), 최상의 방법?

ufoet 2020. 12. 14. 20:24
반응형

상대 시간에 대한 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.RelativeTimeFormatV8 v7.1.179 및 Chrome 71 에서 기본적으로 사용할 수 있습니다 . 이 API가 더 널리 사용 가능 해짐따라 Moment.js , Globalizedate-fns같은 라이브러리 가 기본 상대 시간 형식 지정 기능을 선호하는 하드 코딩 된 CLDR 데이터베이스에 대한 종속성을 제거하여로드 시간 성능을 개선하고 구문 분석을 수행 할 수 있습니다. -컴파일 시간 성능, 런타임 성능 및 메모리 사용량.


타다! Timeago : http://timeago.yarp.com/

아 잠깐만-플러그인없이? 그렇다면 그 이유는 무엇입니까? 나는 당신이 플러그인 파일을 열고 그것의 내장을 해킹 할 수 있다고 생각한다.


Diego Castillo awnsertimeago.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

참고URL : https://stackoverflow.com/questions/6108819/javascript-timestamp-to-relative-time-eg-2-seconds-ago-one-week-ago-etc-best

반응형