2008-10-03 15 views
5

Lassen Sie uns sagen, dass ich zwei Strings in JavaScript haben:Wie kontextuelle Differenz zwischen zwei Zeitstempeln in JavaScript rendern?

var date1 = '2008-10-03T20:24Z' 
var date2 = '2008-10-04T12:24Z' 

Wie würde ich zu einem Ergebnis kommen wie so:

'4 weeks ago' 

oder

'in about 15 minutes' 

(sollte Vergangenheit unterstützen und Zukunft).

Es gibt Lösungen für die Vergangenheit Diffs, aber ich habe noch eine mit Unterstützung für zukünftige Zeit Diffs zu finden.

Dies sind die Lösungen, die ich versucht:

John Resig's Pretty Date und Zach Leatherman's modification

Bonuspunkte für eine jQuery-Lösung.

+0

Sie haben bereits eine Lösung für vergangene Diffs? Tauschen Sie die Daten aus, lösen Sie, entfernen Sie das "Vor" vom Ende, vor "In ungefähr". Erledigt. ;) – moonshadow

+0

nur gepostet Lösungen Ich habe versucht - Zukunft Termine funktionieren nicht so gut –

Antwort

7

Mit Blick auf die Lösungen, die Sie verknüpft haben ... ist es eigentlich so einfach wie mein frivoler Kommentar!

Hier ist eine Version des Zach Leatherman-Codes, die "In" für zukünftige Termine für Sie vorstellt. Wie Sie sehen können, sind die Änderungen sehr gering.

function humane_date(date_str){ 
     var time_formats = [ 
      [60, 'Just Now'], 
      [90, '1 Minute'], // 60*1.5 
      [3600, 'Minutes', 60], // 60*60, 60 
      [5400, '1 Hour'], // 60*60*1.5 
      [86400, 'Hours', 3600], // 60*60*24, 60*60 
      [129600, '1 Day'], // 60*60*24*1.5 
      [604800, 'Days', 86400], // 60*60*24*7, 60*60*24 
      [907200, '1 Week'], // 60*60*24*7*1.5 
      [2628000, 'Weeks', 604800], // 60*60*24*(365/12), 60*60*24*7 
      [3942000, '1 Month'], // 60*60*24*(365/12)*1.5 
      [31536000, 'Months', 2628000], // 60*60*24*365, 60*60*24*(365/12) 
      [47304000, '1 Year'], // 60*60*24*365*1.5 
      [3153600000, 'Years', 31536000], // 60*60*24*365*100, 60*60*24*365 
      [4730400000, '1 Century'], // 60*60*24*365*100*1.5 
     ]; 

     var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," "), 
      dt = new Date, 
      seconds = ((dt - new Date(time) + (dt.getTimezoneOffset() * 60000))/1000), 
      token = ' Ago', 
      prepend = '', 
      i = 0, 
      format; 

     if (seconds < 0) { 
      seconds = Math.abs(seconds); 
      token = ''; 
      prepend = 'In '; 
     } 

     while (format = time_formats[i++]) { 
      if (seconds < format[0]) { 
       if (format.length == 2) { 
        return (i>1?prepend:'') + format[1] + (i > 1 ? token : ''); // Conditional so we don't return Just Now Ago 
       } else { 
        return prepend + Math.round(seconds/format[2]) + ' ' + format[1] + (i > 1 ? token : ''); 
       } 
      } 
     } 

     // overflow for centuries 
     if(seconds > 4730400000) 
      return Math.round(seconds/4730400000) + ' Centuries' + token; 

     return date_str; 
    }; 
+0

Mein Gehirn ist langsam. Vielen Dank! :) –

3

Heh - schrieb ich tatsächlich eine Funktion genau dieses Ding gestern zu tun (und es ist nicht auf diesem Computer so werde ich einfach zu versuchen, um es zu merken)

ich das Datum der Prototypen-Klasse erweitert, aber das könnte recht einfach in eine normale Funktion gebracht werden.

Date.prototype.toRelativeTime = function(otherTime) { 
    // if no parameter is passed, use the current date. 
    if (otherTime == undefined) otherTime = new Date(); 

    var diff = Math.abs(this.getTime() - otherTime.getTime())/1000; 

    var MIN = 60,  // some "constants" just 
     HOUR = 3600,  // for legibility 
     DAY = 86400 
    ; 
    var out, temp; 
    if (diff < MIN) { 
     out = "Less than a minute"; 

    } else if (diff < 15 * MIN) { 
     // less than fifteen minutes, show how many minutes 
     temp = Math.round(diff/MIN); 
     out = temp + " minute" + (temp == 1 ? "" : "s"); 
     // eg: 12 minutes 
    } else if (diff < HOUR) { 
     // less than an hour, round down to the nearest 5 minutes 
     out = (Math.floor(diff/(5 * MIN)) * 5) + " minutes"; 
    } else if (diff < DAY) { 
     // less than a day, just show hours 
     temp = Math.round(diff/HOUR); 
     out = temp + " hour" + (temp == 1 ? "" : "s"); 
    } else if (diff < 30 * DAY) { 
     // show how many days ago 
     temp = Math.round(diff/DAY); 
     out = temp + " day" + (temp == 1 ? "" : "s"); 
    } else if (diff < 90 * DAY) { 
     // more than 30 days, but less than 3 months, show the day and month 
     return this.getDate() + " " + this.getShortMonth(); // see below 
    } else { 
     // more than three months difference, better show the year too 
     return this.getDate() + " " + this.getShortMonth() + " " + this.getFullYear(); 
    } 
    return out + (this.getTime() > otherTime.getTime() ? " from now" : " ago"); 

}; 

Date.prototype.getShortMonth = function() { 
    return ["Jan", "Feb", "Mar", 
      "Apr", "May", "Jun", 
      "Jul", "Aug", "Sep", 
      "Oct", "Nov", "Dec"][this.getMonth()]; 
}; 

// sample usage: 
var x = new Date(2008, 9, 4, 17, 0, 0); 
alert(x.toRelativeTime()); // 9 minutes from now 

x = new Date(2008, 9, 4, 16, 45, 0, 0); 
alert(x.toRelativeTime()); // 6 minutes ago 

x = new Date(2008, 11, 1); // 1 Dec 

x = new Date(2009, 11, 1); // 1 Dec 2009 
Verwandte Themen