2009-01-12 7 views
1

J'ai une page qui utilise actuellement le datetime microformat pour afficher un horodatage, mais je n'ai été montrant le temps lisible par l'homme pour mon propre fuseau horaire:Comment puis-je convertir datetime microformat en heure locale en javascript?

<abbr class="published" title="2009-01-09T09:16:00-05:00"> 
Friday, January 9, 2009 at 9:16 am (EST)</abbr> 

Ce que je voudrais faire est rewrite innerHTML pour la balise abbr doit avoir le même format, mais dans le fuseau horaire local de l'utilisateur. Donc, pour un lecteur à Seattle, le doit être converti ci-dessus pour:

<abbr class="published" title="2009-01-09T09:16:00-05:00"> 
Friday, January 9, 2009 at 6:16 am (PST)</abbr> 

Je l'ai regardé le Javascript Date object, ce qui me permet d'obtenir le fuseau horaire local OFFSET. Mais j'ai quelques problèmes:

  1. Je ne vois pas un moyen facile de créer un nouvel objet Date à partir d'un horodatage ISO-8601. (Je suppose que je pourrais analyser avec des sous-chaînes ou regex s'il n'y a pas de manière plus rapide.)

  2. Je ne vois pas un moyen d'obtenir l'abréviation nommée pour le fuseau horaire. Par exemple, pour un lecteur à Seattle, je voudrais que l'heure soit "(PST)" ajoutée à la fin, sinon il n'est pas clair pour cet utilisateur que l'horodatage a été converti (surtout s'il est un visiteur fréquent et s'est habitué au fait que mes temps sont en EST).

Répondre

5

Voici le code de la mine qui parse un horodatage ISO:

function isoDateStringToDate (datestr) { 
    if (! this.re) { 
    // The date in YYYY-MM-DD or YYYYMMDD format 
    var datere = "(\\d{4})-?(\\d{2})-?(\\d{2})"; 
    // The time in HH:MM:SS[.uuuu] or HHMMSS[.uuuu] format 
    var timere = "(\\d{2}):?(\\d{2}):?(\\d{2}(?:\\.\\d+)?)"; 
    // The timezone as Z or in +HH[:MM] or -HH[:MM] format 
    var tzre = "(Z|(?:\\+|-)\\d{2}(?:\\:\\d{2})?)?"; 
    this.re = new RegExp("^" + datere + "[ T]" + timere + tzre + "$"); 
    } 

    var matches = this.re.exec(datestr); 
    if (! matches) 
    return null; 

    var year = matches[1]; 
    var month = matches[2] - 1; 
    var day = matches[3]; 
    var hour = matches[4]; 
    var minute = matches[5]; 
    var second = Math.floor(matches[6]); 
    var ms = matches[6] - second; 
    var tz = matches[7]; 
    var ms = 0; 
    var offset = 0; 

    if (tz && tz != "Z") { 
    var tzmatches = tz.match(/^(\+|-)(\d{2})(\:(\d{2}))$/); 
    if (tzmatches) { 
     offset = Number(tzmatches[2]) * 60 + Number(tzmatches[4]); 
     if (tzmatches[1] == "-") 
     offset = -offset; 
    } 
    } 

    offset *= 60 * 1000; 
    var dateval = Date.UTC(year, month, day, hour, minute, second, ms) - offset; 

    return new Date(dateval); 
} 

Malheureusement, il ne gère pas les abréviations fuseaux horaires non plus. Vous devez modifier l'expression "tzre" pour accepter les lettres, et la seule solution que je connaisse pour traiter les abréviations de fuseau horaire en Javascript est d'avoir une table de consultation que vous tenez à jour manuellement en cas de changements dans les régions. heure d'été.

+0

Vous avez utilisé la variable "ms" deux fois de suite, annulant ainsi son utilisation précédente. –

+0

Bonne prise, que "var ms = 0;" ne devrait pas être là du tout. Rétrospectivement, je suis à peu près sûr que le regex correspondant au fuseau horaire manque aussi un quantificateur zéro ou un. – Tony

0

EcmaScript a formalisé l'ajout d'une chaîne de style ISO-8601 en tant qu'imput pour une date JavaScript. Comme la plupart des implémentations JS ne supportent pas cela, j'ai créé un wrapper à l'objet Date, qui a cette fonctionnalité. Si vous définissez les balises de titre à sortir en décalage UTC/GMT/Z/Zulu, vous pouvez utiliser mon EcmaScript 5 extensions for JS's Date object.

Pour les valeurs DateTime qui doivent être utilisées dans les scripts côté client, j'essaie généralement de toujours faire ce qui suit. Stocker la date et l'heure dans la zone UTC (même dans les bases de données). Transmettre les dates et heures dans la zone UTC. Du client au serveur, vous pouvez utiliser la méthode .toISOString() dans le lien ci-dessus. Du serveur au client, c'est relativement facile.

Via jQuery (avec extension):

$('.published').each(function(){ 
    var dtm = new Date(this.title); 
    if (!isNaN(dtm)) { 
    this.text(dtm.toString()); 
    } 
});

Je ne me souviens pas si j'ajouté le support pour la date fois non utc dans l'entrée, mais ne serait pas trop difficile d'en rendre compte.

Questions connexes