2010-09-21 4 views
2

Je rends cet objet JSON:Pourquoi ce DateParser ne fonctionne-t-il pas dans Safari?

[{"created_at":"2010-09-21T20:41:28Z","subject":"hello world"}] 

Puis-je utiliser cet analyseur de date pour l'analyser (voir ci-dessous), mais il ne fonctionne que dans Chrome 6.0.4, Firefox 3.6.8, mais pas Safari 5.0.2 --- Je reçois des erreurs NaN. Ce qui donne?

Date.prototype.toRelativeTime = function(now_threshold) { 
var delta = new Date() - this; 

now_threshold = parseInt(now_threshold, 10); 

if (isNaN(now_threshold)) { 
    now_threshold = 0; 
} 

if (delta <= now_threshold) { 
    return 'Just now'; 
} 

var units = null; 
var conversions = { 
    millisecond: 1, // ms -> ms 
    second: 1000, // ms -> sec 
    minute: 60,  // sec -> min 
    hour: 60,  // min -> hour 
    day: 24,  // hour -> day 
    month: 30,  // day -> month (roughly) 
    year: 12  // month -> year 
}; 

for (var key in conversions) { 
    if (delta < conversions[key]) { 
    break; 
    } else { 
    units = key; // keeps track of the selected key over the iteration 
    delta = delta/conversions[key]; 
    } 
} 

// pluralize a unit when the difference is greater than 1. 
    delta = Math.floor(delta); 
if (delta !== 1) { units += "s"; } 
return [delta, units, "ago"].join(" "); 
    }; 

/* 
* Wraps up a common pattern used with this plugin whereby you take a String 
* representation of a Date, and want back a date object. 
*/ 
    Date.fromString = function(str) { 
     return new Date(Date.parse(str)); 
    }; 

Répondre

4

Le problème est que le soutien du constructeur Date ISO 8601 n'est pas présent dans tous les navigateurs web. Vous pouvez effectuer les opérations suivantes:

Date.prototype.setISO8601 = function (string) { 
    var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" + 
     "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" + 
     "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"; 
    var d = string.match(new RegExp(regexp)); 

    var offset = 0; 
    var date = new Date(d[1], 0, 1); 

    if (d[3]) { date.setMonth(d[3] - 1); } 
    if (d[5]) { date.setDate(d[5]); } 
    if (d[7]) { date.setHours(d[7]); } 
    if (d[8]) { date.setMinutes(d[8]); } 
    if (d[10]) { date.setSeconds(d[10]); } 
    if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); } 
    if (d[14]) { 
     offset = (Number(d[16]) * 60) + Number(d[17]); 
     offset *= ((d[15] == '-') ? 1 : -1); 
    } 

    offset -= date.getTimezoneOffset(); 
    time = (Number(date) + (offset * 60 * 1000)); 
    this.setTime(Number(time)); 
} 

alors votre code pourrait ressembler à ceci:

var d = new Date("2010-09-13T11:51:50.9418504+02:00"); 
if (isNaN(d)) { 
    //alert("Date constructor not support ISO8601!"); 
    d = new Date(); 
    d.setISO8601("2010-09-13T11:51:50.9418504+02:00"); 
} 

Le code n'est pas de moi. Je l'ai trouvé sur internet, mais je n'ai pas trouvé la source originale.

+0

fonctionne comme un charme! Merci! –

0
Tue, 21 Sep 2010 20:06:45 UTC +00:00 

est une représentation lisible par l'homme et ActiveSupport ne sera jamais utiliser ce format pour convertir les dates en JSON, à moins que vous patcher le singe (mais non recommandé). Toutefois, vous pouvez utiliser l'option config.active_support.use_standard_json_time_format pour toggle the standard json time format. Si true, Rails utilisera la représentation de date de type XML. Sinon, il utilisera un format personnalisé.

Voici le code source

class Time 
    def as_json(options = nil) #:nodoc: 
    if ActiveSupport.use_standard_json_time_format 
     xmlschema 
    else 
     %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}) 
    end 
    end 
end 
+0

merci pour une telle grande réponse! il s'avère, cependant, que le problème n'était pas avec le format, mais avec une interaction de bogue de safari avec mon assistant de date. –

1

J'aime ajouter quelques mots à la première réponse:

Tout d'abord, la réponse est parfaite. J'espère que quelqu'un peut m'en dire plus sur sa source?

Deuxièmement, il y a des erreurs dans les expressions régulières:

  • le point de milliseconde dans le temps n'est pas cité correctement
  • l'expression rationnelle ne vérifie pas la chaîne entière. Dans mon cas, j'ai obtenu un résultat même lorsque le fuseau horaire n'est pas détecté correctement
  • cela m'amène au troisième problème: la norme ISO8601 permet d'omettre les caractères ":" et "-".

Je corrige l'expression rationnelle à l'exception du troisième point (en raison d'un manque de temps pour les essais):

var regexp = "^([0-9]{4})(-([0-9]{2})(-([0-9]{2})" + 
    "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\\.([0-9]+))?)?" + 
    "(Z|(([-+])([0-9]{2}):?([0-9]{2})))?)?)?)?$"; 
Questions connexes