jQuery Time ago from a timestamp?

18,743

Solution 1

I had the same problem. I'm using Unix timestamps which are generated from PHP, so I decided to do a quick hack and extend the parsing function of jQuery timeago to handle timestamps additionally. Works like a charm. Simply look for the Parse function at around line 79 in the jquery.timeago.js file, and replace with the following:

  parse: function(iso8601) {
  if ((iso8601 - 0) == iso8601 && iso8601.length > 0) { // Checks if iso8601 is a unix timestamp
    var s = new Date(iso8601);
    if (isNaN(s.getTime())) { // Checks if iso8601 is formatted in milliseconds
      var s = new Date(iso8601 * 1000); //if not, add milliseconds 
    }
    return s;
  }

  var s = $.trim(iso8601);
  s = s.replace(/-/,"/").replace(/-/,"/");
  s = s.replace(/T/," ").replace(/Z/," UTC");
  s = s.replace(/([\+-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
  return new Date(s);
},

Solution 2

Here is something in JavaScript using nothing but Unix timestamps.

var d1;
var d2;
d1 = (new Date()).getTime(); setTimeout( function() { d2 = (new Date()).getTime(); }, 5000 );
var secondsElapsed = (d2 - d1) / 1000;
secondsElapsed; // 5 seconds

Now, you can either store a timestamp in a JavaScript variable in the same scope as your "timeago" function, or your can store it in an HTML element. As mentioned, the time element is an HTML 5 element. You could do something like:


<p class="timestamp" style="display: none;">123456</p>

Then maybe you have a comment item like:


<div class="comment">
  <p>Lorem ipsum et dolor...</p&gt
  <p class="timestamp" style="display: none;">123456</p>
</div>

You could then get the timestamp for a comment by (assuming jQuery since you mentioned it):


var tstamps = $('.comment .timestamp'); // array of comment timestamps
var timeago = ( (new Date()).getTime() - tstamps[0].html() ) / 1000;

It's a bit hackish, but it would work (if I did it right).

Solution 3

I like to use DateJS.com which is a date / time javascript library. You can do cool stuff like this (display 2 hours ago in a <span id='myfield'></span>):

$('#myfield').text( (2).hours().ago().toString("HH:mm") );
Share:
18,743
JasonDavis
Author by

JasonDavis

PHP/MySQL is my flavor of choice however more recently JavaScript is really becoming something I enjoy developing with! Writing code since 2000' Currently working heavily with SugarCRM + Launching my Web Dev company ApolloWebStudio.com "Premature optimization is not the root of all evil, lack of proper planning is the root of all evil." Twitter: @JasonDavisFL Work: Apollo Web Studio - https://www.apollowebstudio.com Some of my Web Dev skills, self rated... +------------+--------+------+--------------+ | Skill | Expert | Good | Intermediate | +------------+--------+------+--------------+ | PHP | X | | | +------------+--------+------+--------------+ | MySQL | X | | | +------------+--------+------+--------------+ | Javascript | X | | +------------+--------+------+--------------+ | jQuery | X | | +------------+--------+------+--------------+ | CSS+CSS3 | X | | +------------+--------+------+--------------+ | HTML+HTML5 | X | | | +------------+--------+------+--------------+ | Photoshop | | X | | +------------+--------+------+--------------+ | Web Dev | X | | | +------------+--------+------+--------------+ | SugarCRM | X | | | +------------+--------+------+--------------+ | Magento | | X | | +------------+--------+------+--------------+ | WordPress | X | | | +------------+--------+------+--------------+ | SEO | X | | | +------------+--------+------+--------------+ | Marketing | X | | | +------------+--------+------+--------------+ |Social Media| X | | | +------------+--------+------+--------------+

Updated on June 17, 2022

Comments

  • JasonDavis
    JasonDavis almost 2 years

    Below is a really nice time ago plugin for jQuery, very similar to what they use here on SO. The problem for me is that it uses this to convert time.

    <time class="timeago" datetime="2008-07-17T09:24:17Z">July 17, 2008</time>
    

    That would be great except that I store time on my site in UTC timestamp and not as a formatted time, is there a way to convert something like this to use a timestamp? I know in PHP I could convert my timestamp to this format but it seems like overkill with converting a LOT of times on 1 page in PHP. I could be wrong, anyone else do this in jquery but from real timestamp?

    Also I currently do this in PHP on a site to show "2 hours 4 minutes ago" but wou7ld it be better to use javascript for this instead of PHP?

    /*
     * timeago: a jQuery plugin, version: 0.8.1 (2010-01-04)
     * @requires jQuery v1.2.3 or later
     *
     * Timeago is a jQuery plugin that makes it easy to support automatically
     * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
     *
     * For usage and examples, visit:
     * http://timeago.yarp.com/
     * Copyright (c) 2008-2010, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org)
     */
    (function($) {
      $.timeago = function(timestamp) {
        if (timestamp instanceof Date) return inWords(timestamp);
        else if (typeof timestamp == "string") return inWords($.timeago.parse(timestamp));
        else return inWords($.timeago.datetime(timestamp));
      };
      var $t = $.timeago;
    
      $.extend($.timeago, {
        settings: {
          refreshMillis: 60000,
          allowFuture: false,
          strings: {
            prefixAgo: null,
            prefixFromNow: null,
            suffixAgo: "ago",
            suffixFromNow: "from now",
            ago: null, // DEPRECATED, use suffixAgo
            fromNow: null, // DEPRECATED, use suffixFromNow
            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"
          }
        },
        inWords: function(distanceMillis) {
          var $l = this.settings.strings;
          var prefix = $l.prefixAgo;
          var suffix = $l.suffixAgo || $l.ago;
          if (this.settings.allowFuture) {
            if (distanceMillis < 0) {
              prefix = $l.prefixFromNow;
              suffix = $l.suffixFromNow || $l.fromNow;
            }
            distanceMillis = Math.abs(distanceMillis);
          }
    
          var seconds = distanceMillis / 1000;
          var minutes = seconds / 60;
          var hours = minutes / 60;
          var days = hours / 24;
          var years = days / 365;
    
          var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
            seconds < 90 && substitute($l.minute, 1) ||
            minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
            minutes < 90 && substitute($l.hour, 1) ||
            hours < 24 && substitute($l.hours, Math.round(hours)) ||
            hours < 48 && substitute($l.day, 1) ||
            days < 30 && substitute($l.days, Math.floor(days)) ||
            days < 60 && substitute($l.month, 1) ||
            days < 365 && substitute($l.months, Math.floor(days / 30)) ||
            years < 2 && substitute($l.year, 1) ||
            substitute($l.years, Math.floor(years));
    
          return $.trim([prefix, words, suffix].join(" "));
        },
        parse: function(iso8601) {
          var s = $.trim(iso8601);
          s = s.replace(/-/,"/").replace(/-/,"/");
          s = s.replace(/T/," ").replace(/Z/," UTC");
          s = s.replace(/([\+-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
          return new Date(s);
        },
        datetime: function(elem) {
          // jQuery's `is()` doesn't play well with HTML5 in IE
          var isTime = $(elem).get(0).tagName.toLowerCase() == 'time'; // $(elem).is('time');
          var iso8601 = isTime ? $(elem).attr('datetime') : $(elem).attr('title');
          return $t.parse(iso8601);
        }
      });
    
      $.fn.timeago = function() {
        var self = this;
        self.each(refresh);
    
        var $s = $t.settings;
        if ($s.refreshMillis > 0) {
          setInterval(function() { self.each(refresh); }, $s.refreshMillis);
        }
        return self;
      };
    
      function refresh() {
        var data = prepareData(this);
        if (!isNaN(data.datetime)) {
          $(this).text(inWords(data.datetime));
        }
        return this;
      }
    
      function prepareData(element) {
        element = $(element);
        if (element.data("timeago") === undefined) {
          element.data("timeago", { datetime: $t.datetime(element) });
          var text = $.trim(element.text());
          if (text.length > 0) element.attr("title", text);
        }
        return element.data("timeago");
      }
    
      function inWords(date) {
        return $t.inWords(distance(date));
      }
    
      function distance(date) {
        return (new Date().getTime() - date.getTime());
      }
    
      function substitute(stringOrFunction, value) {
        var string = $.isFunction(stringOrFunction) ? stringOrFunction(value) : stringOrFunction;
        return string.replace(/%d/i, value);
      }
    
      // fix for IE6 suckage
      document.createElement('abbr');
      document.createElement('time');
    })(jQuery);