Come convertire il tempo correttamente attraverso i fusi orari?

Diciamo che l’utente in CA, USA prende una data, ora e fuso orario:

La maratona della birra in tutto il mondo inizia l’8/15/ 2013 alle 10:00, UTC-08: 00

Un altro utente, in Europa centrale, apre la pagina in cui vengono visualizzate questa data e ora. Non vuole fare calcoli temporali (aveva già poche birre). Vuole solo vedere questa data e ora:

15/08/2013 19:00

Dato che il browser riceve le informazioni su data e ora, come inserite dall’utente in California:

    C’è un modo, in javascript , senza servizi web esterni , di fare una conversione corretta? Cioè, per rilevare che il 10am UTC-08: 00 dovrebbe effettivamente essere 10am UTC-07: 00, dal momento che è l’ora legale.

    Forse ho capito male fin dall’inizio, ma non voglio permettere all’utente che sta entrando di pensare se debba scegliere UTC-08: 00 (PST) o UTC-07: 00 (PDT). Presumo che dal momento che il fuso orario standard in CA è PST, le persone non passano a pensare in PDT in estate. O loro ?!

    Nell’Europa centrale, la data standard è UTC + 01: 00, la data diurna è UTC + 02: 00. Pertanto, la differenza tra CA e Europa dovrebbe essere di 9 ore, ad eccezione di due periodi in un anno, quando l’una o l’altra area passa tra le modalità di salvataggio normale e diurna.

    Aggiornare:

    Dopo un po ‘di più pensando e leggendo i commenti, quello di cui avrei idealmente bisogno è questo:

    var utcOffset = f('2013-08-15T10:00', 'America/Los_Angeles'); // utcOffset == "-07:00" var utcOffset = f('2013-11-15T10:00', 'America/Los_Angeles'); // utcOffset == "-08:00" 

    Finora, sembra che il plugin time.jes / timezone , suggerito da Guido Preite, sia in grado di farlo (più o meno).

    Qualunque altro modo, usando le API del browser?

    C’è un modo, in javascript, senza servizi web esterni, di fare una conversione corretta? Cioè, per rilevare che il 10am UTC-08: 00 dovrebbe effettivamente essere 10am UTC-07: 00, dal momento che è l’ora legale.

    10: 00-8 e 10: 00-7 sono due diversi momentjs nel tempo. Sono uguali a 18: 00Z e 17: 00Z rispettivamente (Z = UTC). Quando si misura in termini di offset, l’ora legale non entra nell’immagine. Mai.

    Presumo che dal momento che il fuso orario standard in CA è PST, le persone non passano a pensare in PDT in estate. O loro ?!

    In generale, le persone pensano solo a “Pacific Time”, e ciò significa sia la PST in inverno, sia la PDT in estate. Ma i computer sono più precisi. Quando vedi PST, significa UTC-8. Quando vedi PDT, significa UTC-7. Non sarebbe valido etichettare utilizzando un modulo mentre si fa riferimento contemporaneamente all’offset dell’altro.

    Le abbreviazioni dei fusi orari possono essere ambigue . Idealmente, quando si fa riferimento alla zona in modo programmatico, si dovrebbe usare il nome della zona IANA, come America/Los_Angeles . Tuttavia, questo non è attualmente ansible in tutti i runtime JavaScript senza una libreria. ( Stanno lavorando su questo però .)

    Nell’Europa centrale, la data standard è UTC + 01: 00, la data diurna è UTC + 02: 00. Pertanto, la differenza tra CA e Europa dovrebbe essere di 9 ore, ad eccezione di due periodi in un anno, quando l’una o l’altra area passa tra le modalità di salvataggio normale e diurna.

    Corretta. Potrebbero essere 8, 9 o 10 ore di distanza. Passano però a tempi completamente diversi, quindi non provare a gestirlo da soli.

    Finora, sembra che il plugin time.jes / timezone, suggerito da Guido Preite, sia in grado di farlo (più o meno).

    Moment-timezone è una grande libreria. Tuttavia, dallo scenario che hai descritto, non penso che tu debba preoccuparti della conversione del fuso orario tanto quanto stai pensando. Vedi se puoi seguire questa logica:

    1. L’utente in California immette una data e un’ora in una casella di testo.
    2. Leggi il valore di tale casella di testo in una stringa e lo analizzi in una data:

       var dt = new Date("8/15/2013 10:00"); 

      o usando moment.js:

       var m = moment("8/15/2013 10:00", "M/D/YYYY HH:mm"); 
    3. Poiché ciò viene eseguito sul computer dell’utente, JavaScript assumerà automaticamente che questa è una data e un’ora locali . Non è necessario fornire alcuna informazione sull’offset o sul fuso orario.

    4. Ciò significa che a causa delle transizioni DST, il tempo inserito potrebbe essere non valido o ambiguo. JavaScript non fa un ottimo lavoro nel maneggiarlo, infatti – otterrai risultati diversi su browser diversi. Se vuoi essere univoco, forniresti un offset.

       // PST var dt = new Date("3/11/2013 1:00 UTC-08:00"); // PDT var dt = new Date("3/11/2013 1:00 UTC-07:00"); 
    5. Una volta che hai una Date (o un moment ), allora puoi valutare il suo equivalente UTC:

       var s = dt.toISOString(); // 2013-08-15T17:00:00Z 

      è lo stesso con moment.js, ma avrai un supporto browser migliore:

       var s = m.toISOString(); // 2013-08-15T17:00:00Z 
    6. Memorizzi quel valore UTC nel tuo database.

    7. L’altro utente in Europa centrale arriva e carica i dati.

    8. Lo metti in una Date o un moment in JavaScript:

       var dt = new Date("2013-08-15T17:00:00Z"); 

      o con moment.js (di nuovo, migliore supporto del browser)

       var m = moment("2013-08-15T17:00:00Z") 
    9. Poiché JavaScript conosce le regole del fuso orario del computer locale, ora puoi visualizzare questa data e verrà visualizzata con il fuso orario dell’Europa centrale:

       var s = dt.ToString(); // browser specific output // ex: "Thu Aug 15 2013 19:00:00 GMT+0200 (Central Europe Daylight Time)" 

      o con moment.js, puoi controllare meglio il formato di output

       var s = m.format("DD/MM/YYYY HH:mm"); // "15/08/2013 19:00" 

      potresti anche lasciare che time.js decida quale formato localizzato debba essere prodotto:

       var s = m.format("llll"); // "Thu, 15 Aug 2013 19:00" 

    Riassumendo: se sei interessato solo alla conversione da e verso il fuso orario locale (qualunque sia la zona), puoi fare tutto con la sola Date . Moment.js renderà le cose più facili per l’analisi e la formattazione, ma non è assolutamente necessario.

    Esistono solo alcuni scenari che richiedono una libreria dei fusi orari (come la zona momento o altri).

    • Vuoi convertire in o da una zona che non è il fuso orario locale o UTC.

    • Stai lavorando con date che sono nel passato, e da allora c’è stata una modifica alle regole del fuso orario o alle regole dell’ora legale, e hai date che sarebbero interpretate in modo diverso secondo le nuove regole rispetto a quelle vecchie. Questo è un po ‘tecnico, ma succede. Leggi di più qui e qui .

    Il costruttore predefinito crea un’istanza dell’ora locale

     var localDate = new Date(); 

    Non posso testarlo adesso, ma dovresti essere in grado di fornire il tuo datetime (come parametro al costruttore) ..

     var eventDate = [SOMEDATE]; var localDate = new Date(eventDate); 

    ..e quindi dovresti essere in grado di chiamare le funzioni dell’object Date come getMonth, che restituisce i dati nel fuso orario locale. Come scritto su: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

    Nota 1: senza server = non esiste un server | db? Se c’è, la data deve essere salvata come UTC in db e caricarla come ora locale per ogni utente .. in questo modo non devi preoccuparti delle conversioni.

    Nota 2: questa domanda ha un codice che mostra come ottenere la differenza del fuso orario: come ottenere l’ora locale esatta del client?

    Ho sviluppato questa soluzione sulla base di altri esempi … spero che questo funzioni per te! Disponibile su jsfiddle .

     /* * Author: Mohammad M. AlBanna * Website: MBanna.me * Description: Get the current time in different time zone */ //Check daylight saving time prototype Date.prototype.stdTimezoneOffset = function() { var jan = new Date(this.getFullYear(), 0, 1); var jul = new Date(this.getFullYear(), 6, 1); return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); } Date.prototype.dst = function() { return this.getTimezoneOffset() < this.stdTimezoneOffset(); } var today = new Date(); var isDST = today.dst() ? true : false; var pstOffset = isDST ? 7 : 8; var cstOffset = isDST ? 5 : 6; var estOffset = isDST ? 4 : 5; var gmtOffset = 1; pstOffset = pstOffset * 60 * 60 * 1000; cstOffset = cstOffset * 60 * 60 * 1000; estOffset = estOffset * 60 * 60 * 1000; gmtOffset = gmtOffset * 60 * 60 * 1000; var todayMillis = today.getTime(); var timeZoneOffset = (today.getTimezoneOffset() * 60 * 1000); var curretPST = todayMillis - pstOffset; var curretCST = todayMillis - cstOffset; var curretEST = todayMillis - estOffset; var curretGMT = todayMillis - gmtOffset; addP("PST Time : " + new Date(curretPST).toUTCString()); addP("CST Time : " + new Date(curretCST).toUTCString()); addP("EST Time : " + new Date(curretEST).toUTCString()); addP("GMT Time : " + new Date(curretGMT).toUTCString()); addP("Local Time : " + new Date(today.getTime() - timeZoneOffset ).toUTCString()); function addP(value){ var p = document.createElement("p"); p.innerHTML = value; document.body.appendChild(p); }