it-swarm.it

Visualizza data/ora nel formato locale dell'utente e l'offset temporale

Voglio che il server pubblichi sempre le date in UTC nel codice HTML e che JavaScript sul sito del cliente lo converta nel fuso orario locale dell'utente.

Bonus se posso stampare nel formato data locale dell'utente.

145
kch

Sembra il modo più infallibile per iniziare con una data UTC è quello di creare un nuovo oggetto Date e utilizzare i metodi setUTC… per impostarlo sulla data/ora desiderata.

Quindi i vari metodi toLocale…String forniranno un output localizzato.

Esempio:

// This would come from the server.
// Also, this whole block could probably be made into an mktime function.
// All very bare here for quick grasping.
d = new Date();
d.setUTCFullYear(2004);
d.setUTCMonth(1);
d.setUTCDate(29);
d.setUTCHours(2);
d.setUTCMinutes(45);
d.setUTCSeconds(26);

console.log(d);                        // -> Sat Feb 28 2004 23:45:26 GMT-0300 (BRT)
console.log(d.toLocaleString());       // -> Sat Feb 28 23:45:26 2004
console.log(d.toLocaleDateString());   // -> 02/28/2004
console.log(d.toLocaleTimeString());   // -> 23:45:26

Alcuni riferimenti:

148
kch

Per i nuovi progetti, basta usare moment.js

Questa domanda è piuttosto vecchia, quindi moment.js non esisteva in quel momento, ma per i nuovi progetti, semplifica molto le attività come questa. 

È meglio analizzare la stringa della data da UTC come segue (creare una stringa ISO-8601 compatibile sul server per ottenere risultati coerenti su tutti i browser):

var m = moment("2013-02-08T09:30:26Z");

Ora basta usare m nell'applicazione, moment.js ha come default il fuso orario locale per le operazioni di visualizzazione. Ci sono molti modi per formattare i valori di data e ora o estrapolarne parti.

Puoi persino formattare un oggetto momento nelle impostazioni locali dell'utente come questo:

m.format('LLL') // Returns "February 8 2013 8:30 AM" on en-us

Per trasformare un oggetto moment.js in un fuso orario diverso (ad esempio né locale né UTC), avrai bisogno dell'estensione del fuso orario moment.js . Quella pagina ha anche alcuni esempi, è piuttosto semplice da usare.

61
theDmi

Puoi usare new Date().getTimezoneOffset()/60 per il fuso orario. Esiste anche un metodo toLocaleString() per visualizzare una data usando le impostazioni locali dell'utente.

Ecco l'intera lista: Lavorare con le date

19
jop

Una volta creato il tuo oggetto data, ecco uno snippet per la conversione:

La funzione accetta un oggetto Date formattato in UTC e una stringa di formato.
Avrai bisogno di un prototipo Date.strftime.

function UTCToLocalTimeString(d, format) {
    if (timeOffsetInHours == null) {
        timeOffsetInHours = (new Date().getTimezoneOffset()/60) * (-1);
    }
    d.setHours(d.getHours() + timeOffsetInHours);

    return d.strftime(format);
}
6
simianarmy

Ecco cosa ho usato nei progetti precedenti:

var myDate = new Date();
var tzo = (myDate.getTimezoneOffset()/60)*(-1);
//get server date value here, the parseInvariant is from MS Ajax, you would need to do something similar on your own
myDate = new Date.parseInvariant('<%=DataCurrentDate%>', 'yyyyMMdd hh:mm:ss');
myDate.setHours(myDate.getHours() + tzo);
//here you would have to get a handle to your span / div to set.  again, I'm using MS Ajax's $get
var dateSpn = $get('dataDate');
dateSpn.innerHTML = myDate.localeFormat('F');
5
Mark

In JS non ci sono modi semplici e multipiattaforma per formattare l'ora locale, al di fuori della conversione di ciascuna proprietà come menzionato sopra. 

Ecco un rapido trucco che uso per ottenere il YYYY-MM-DD locale. Nota che questo è un hack, dato che la data finale non avrà più il fuso orario corretto (quindi devi ignorare il fuso orario). Se ho bisogno di qualcos'altro, uso moment.js. 

var d = new Date();    
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000)
var yyyymmdd = t.toISOString().slice(0,0); 
// 2017-05-09T08:24:26.581Z (but this is not UTC)

D.getTimezoneOffset () restituisce l'offset del fuso orario in minuti e d.getTime () è in ms, quindi x 60.000.

4
Jeremy Chone

Il metodo .getTimezoneOffset() riporta l'offset del fuso orario in minuti, contando "westwards" dal fuso orario GMT/UTC, risultando in un valore di offset che è negativo a ciò a cui si è abituati. (Esempio, il tempo di New York dovrebbe essere riferito a +240 minuti o +4 ore)

Per ottenere un offset fuso orario normale in ore, è necessario utilizzare:

var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60

Dettagli importanti:
Si noti che l'ora legale viene calcolata nel risultato, quindi ciò che questo metodo fornisce è in realtà l'offset time, non l'effettivo offset geografico fuso orario.

3
Már Örlygsson

Con la data dal codice PHP ho usato qualcosa del genere ..

function getLocalDate(php_date) {
  var dt = new Date(php_date);
  var minutes = dt.getTimezoneOffset();
  dt = new Date(dt.getTime() + minutes*60000);
  return dt;
}

Possiamo chiamarlo così

var localdateObj = getLocalDate('2015-09-25T02:57:46');
3
hriziya

Ho mescolato le risposte finora e le ho aggiunte, perché ho dovuto leggerle tutte e indagare ulteriormente per un po 'per visualizzare una stringa di data e ora da db nel formato fuso orario locale dell'utente.

La stringa datetime proviene da un dthon python/Django nel formato: 2016-12-05T15: 12: 24.215Z

Il rilevamento affidabile della lingua del browser in JavaScript non sembra funzionare in tutti i browser (vedere JavaScript per rilevare la preferenza della lingua del browser ), quindi ottengo la lingua del browser dal server.

Python/Django: invia la lingua del browser di richiesta come parametro di contesto:

language = request.META.get('HTTP_ACCEPT_LANGUAGE')
return render(request, 'cssexy/index.html', { "language": language })

HTML: scrivilo in un input nascosto:

<input type="hidden" id="browserlanguage" value={{ language }}/>

JavaScript: ottieni il valore dell'input nascosto, ad es. en-GB, en-US; q = 0.8, en; q = 0.6/e quindi prendere la prima lingua nell'elenco solo tramite la sostituzione e l'espressione regolare

const browserlanguage = document.getElementById("browserlanguage").value;
var defaultlang = browserlanguage.replace(/(\w{2}\-\w{2}),.*/, "$1");

JavaScript: convertire in datetime e formattarlo:

var options = { hour: "2-digit", minute: "2-digit" };
var dt = (new Date(str)).toLocaleDateString(defaultlang, options);

Vedi: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

Il risultato è (la lingua del browser è en-gb): 05/12/2016, 14:58

3
Anja

La soluzione migliore che ho trovato è quella di creare tag [time display = "llll" datetime = "UTC TIME" /] e utilizzare javascript (jquery) per analizzarlo e visualizzarlo in relazione al tempo dell'utente.

http://momentjs.com/ Moment.js 

mostrerà il tempo piacevolmente.

2
Daniel

È possibile utilizzare quanto segue, che riporta l'offset del fuso orario da GMT in minuti: 

new Date().getTimezoneOffset();

Nota : - questa funzione restituisce un numero negativo.

2
dave

getTimeZoneOffset () e toLocaleString sono buoni per il lavoro di base delle date, ma se hai bisogno del vero supporto del fuso orario, guarda a mde's TimeZone.js

Ci sono alcune altre opzioni discusse nella risposta a questa domanda

1
Aeon

Per convertire la data in una data locale utilizzare il metodo LocaleDateString ().

var date = (new Date(str)).toLocaleDateString(defaultlang, options);

Per convertire il tempo in ora locale utilizzare il metodo LocaleTimeString ().

var time = (new Date(str)).toLocaleTimeString(defaultlang, options);
0
Codemaker

// new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]])
var serverDate = new Date(2018, 5, 30, 19, 13, 15); // just any date that comes from server
var serverDateStr = serverDate.toLocaleString("en-US", {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
})
var userDate = new Date(serverDateStr + " UTC");
var locale = window.navigator.userLanguage || window.navigator.language;

var clientDateStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric'
});

var clientDateTimeStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
});

console.log("Server UTC date: " + serverDateStr);
console.log("User's local date: " + clientDateStr);
console.log("User's local date&time: " + clientDateTimeStr);

0
Sergey