2011-05-24 13 views

回答

62

好吧,如果你不太在意準確性,這很容易。微不足道的方法有什麼問題?

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'; 
    } 
} 

工作示例here

您可能想調整它以更好地處理奇異值(例如1 day而不是1 days),如果這樣會讓您感到困擾。

+0

Brill!正是我在找的!我知道基本的原則,但是想要確定它最好的辦法:) – wilsonpage 2011-05-24 10:46:36

5

Tada! Timeago:http://timeago.yarp.com/

哎呀 - 沒有插件?那爲什麼呢?我想你可以打開插件文件,並破解它的膽量。

+0

嗯,這實際上是一個插件。 OP要求不使用解決方案。 – pimvdb 2011-05-24 10:11:45

+0

只是想保持代碼儘可能乾淨並且可以完全自定義。我不認爲這是一個很大的功能。 Poss 10-15行因此不需要插件的其他捆綁功能。 – wilsonpage 2011-05-24 10:13:28

+1

好的,源代碼非常短,看起來好像可以根據您的需求提取,只要您保留MIT許可證標題即可。 http://timeago.yarp.com/jquery.timeago.js – 2011-05-24 10:16:33

13

這裏是確切的模仿Twitter的時間前無插件:

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/

希望它能幫助。

+0

你,先生,知道的東西!非常感謝。爲什麼要使用第三方庫? – zanona 2017-10-12 15:39:20

1

對於任何有興趣的人,我最終創建了一個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'; 
     } 
    }); 
2

Inspirated上Diego Castillo awnser's並在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>

3

日期時間插件存在,因爲它很難得到它的權利。這video explaining date-time inconsistencies將闡明這個問題。

上述所有不帶插件的解決方案都不正確。

用於使用日期和時間使用插件是優選的。在處理它的數百個插件中,我們使用了Moment.js,它正在完成這項工作。

twitter API dcumentation,我們可以看到他們的時間戳格式:

"created_at":"Wed Aug 27 13:08:45 +0000 2008" 

我們可以用它解析與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'); 

要爲diff指定首選的時間單位,我們可以使用isSame方法。例如:

if (now.isSame(postDatetime, 'day')) { 
    const timeUnit = 'days'; 
} 

總體而言,構建是這樣的:

`Posted ${timeAgo} ${timeUnit} ago`; 

參考插件的文檔處理相對時間(即:「那是多久以前」)計算。

1

還有sugar.js併爲此relative功能。

相對 - 輸出的相對單位(「前」或「從現在開始」),以當前日期的字符串。

0

可以使用machinepack,日期時間用於這一目的。定義的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 
}); 
0

如果您需要多種語言並且不想添加像時刻這樣的大型圖書館。從雅虎intl-relativeformat它是一個不錯的解決方案。

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"