Nyxynyx
Nyxynyx

Reputation: 63647

Time Ago undefined in Javascript

I'm using a function prettyDate() below to convert a timestamp into a more friendly format. I do not need a plugin that automatically converts the value in a div into a "Time ago" format.

An API returns timestamps 1400564166115 and 1400695785000. date.now() gives 1400696094406.

Using the code below, the first timestamp 1400564166115 gets converted to 2014-05-20T05:36:06.115Z, where function prettyDate() turns it into Yesterday.

For the second time stamp, 1400695785000 converts to 2014-05-21T18:09:45.000Z, but prettyDate() turns this into undefined. Additionally, day_diff is -1 in this case. diff is -14347.209 and slowly moving towards 0.

Why is it giving undefined, what caused day_diff to be <0?

JSfiddle: http://jsfiddle.net/pWNrS/

Example

var d = new Date(parseInt(1400564166115)).toISOString()
prettyDate(d)    // Yesterday

var e = new Date(parseInt(1400695785000)).toISOString()
prettyDate(e)    // undefined *****WHY?*****

prettyDate()

prettyDate = function(time){
    var date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ")),
        diff = (((new Date()).getTime() - date.getTime()) / 1000),
        day_diff = Math.floor(diff / 86400);

    if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
        return;

    return day_diff == 0 && (
            diff < 60 && "just now" ||
            diff < 120 && "1 minute ago" ||
            diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
            diff < 7200 && "1 hour ago" ||
            diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
        day_diff == 1 && "Yesterday" ||
        day_diff < 7 && day_diff + " days ago" ||
        day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}

// If jQuery is included in the page, adds a jQuery plugin to handle it as well
if ( typeof jQuery != "undefined" )
    jQuery.fn.prettyDate = function(){
        return this.each(function(){
            var date = prettyDate(this.title);
            if ( date )
                jQuery(this).text( date );
        });
    };

Stepping through prettyDate()

date: Wed May 21 2014 18:35:46 GMT-0400 (EDT)

(new Date()).getTime(): 1400697389253

date.getTime(): 1400711746000

diff: -14356.757

day_diff: -1

Upvotes: 2

Views: 1109

Answers (1)

mscdex
mscdex

Reputation: 106696

The problem has to do with loss of timezone information.

When you mutate the ISO string, you're changing assumptions about the date/time being parsed. In the ISO format, the 'Z' indicates that the time given is UTC. However once you strip that out, the date parser no longer has any clues about what time zone to use, so it uses the local time zone and adjusts the time accordingly. This is what causes your diff to be negative (because of your local timezone offset).

A quick fix would be to append ' GMT' to the end of your date/time string before you pass it to new Date(): new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ") + ' GMT'). That is assuming that all dates passed in are UTC/GMT. However, if the browser supports ES5 (e.g. you could test var supportsISO8601 = Date.prototype.toISOString === 'function';, you can just keep it in ISO8601 format and pass the string directly to new Date().

Upvotes: 2

Related Questions