2008-10-03 11 views
5

Powiedzmy mam dwa ciągi w JavaScript:Jak renderować różnice kontekstowe między dwoma znacznikami czasu w JavaScript?

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

Jak przyjdę do wyniku tak:

'4 weeks ago' 

lub

'in about 15 minutes' 

(powinny wspierać przeszłość i przyszłość).

Istnieją rozwiązania dla wcześniejszych różnic, ale jeszcze nie znalazłem żadnego z obsługą przyszłych różnic czasowych.

Są to rozwiązania próbowałem:

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

punkty za rozwiązanie jQuery.

+0

Masz już rozwiązanie dla poprzednich różnic? Zamień daty na daty, rozwiąż, odrzuć "temu" od końca, przed "Wstecz". Gotowe. ;) – moonshadow

+0

właśnie zamieszczone rozwiązania próbowałem - przyszłe daty nie działają tak dobrze –

Odpowiedz

7

Patrząc na rozwiązania, które łączysz ... jest to tak proste, jak mój frywolny komentarz!

Oto wersja kodu Zach Leatherman, który przedkłada "In" dla przyszłych dat. Jak widać, zmiany są bardzo niewielkie.

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

Mój mózg jest powolny. Dzięki! :) –

3

Heh - I rzeczywiście napisał funkcję do zrobienia dokładnie tę rzecz wczoraj (i to nie na tym komputerze, więc będę musiał spróbować go pamiętam)

ja przedłużony klasę Data prototypu, ale można to łatwo wprowadzić w zwykłą funkcję.

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 
Powiązane problemy