it-swarm-pt.tech

Exibir data/hora no formato de localidade e no deslocamento de horário do usuário

Eu quero que o servidor sempre sirva datas em UTC no HTML e que o JavaScript no site do cliente o converta no fuso horário local do usuário.

Bônus se eu puder produzir no formato de data de localidade do usuário.

145
kch

Parece que a maneira mais infalível de começar com uma data UTC é criar um novo objeto Date e usar os métodos setUTC… para configurá-lo para a data/hora que você deseja.

Então os vários métodos toLocale…String fornecerão saída localizada.

Exemplo:

// 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

Algumas referências:

148
kch

Para novos projetos, apenas use moment.js

Essa questão é bem antiga, então moment.js não existia naquela época, mas para novos projetos, isso simplifica muito as tarefas. 

É melhor parse sua string de data a partir do UTC da seguinte maneira (crie uma string compatível com ISO-8601 no servidor para obter resultados consistentes em todos os navegadores):

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

Agora é só usar m em sua aplicação, o moment.js assume como padrão o fuso horário local para operações de exibição. Há muitas maneiras de formatar os valores de data e hora ou extrair partes dela.

Você pode até mesmo formatar um objeto de momento na localidade de usuários como este:

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

Para transformar um objeto moment.js em um fuso horário diferente (ou seja, nem o local nem o UTC), você precisará da extensão de fuso horário moment.js . Essa página também tem alguns exemplos, é bem simples de usar.

61
theDmi

Você pode usar new Date().getTimezoneOffset()/60 para o fuso horário. Há também um método toLocaleString() para exibir uma data usando a localidade do usuário.

Aqui está a lista completa: Trabalhando com datas

19
jop

Depois de criar seu objeto de data, aqui está um snippet para a conversão:

A função usa um objeto Date formatado em UTC e uma string de formatação.
Você precisará de um protótipo 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

Aqui está o que eu usei em projetos anteriores:

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

Em JS, não há maneiras simples e de plataforma cruzada de formatar a data e hora local, fora da conversão de cada propriedade, conforme mencionado acima. 

Aqui está um hack rápido que eu uso para obter o YYYY-MM-DD local. Note que este é um hack, já que a data final não terá mais o fuso horário correto (então você tem que ignorar o fuso horário). Se eu precisar de mais alguma coisa, eu uso o 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)

O d.getTimezoneOffset () retorna o deslocamento do fuso horário em minutos, e o d.getTime () está em ms, portanto o x 60.000.

4
Jeremy Chone

O método .getTimezoneOffset() reporta o deslocamento do fuso horário em minutos, contando "westwards" do fuso horário GMT/UTC, resultando em um valor de offset que é negativo para o que se está acostumado. (Por exemplo, o horário de Nova York seria de +240 minutos ou +4 horas)

Para obter um deslocamento de fuso horário normal em horas, você precisa usar:

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

Detalhe importante:
Observe que o horário de verão é fatorado no resultado - então, o que esse método fornece é realmente o tempo deslocamento - não o geográfico real fuso horário deslocamento.

3
Már Örlygsson

Com data do código PHP eu usei algo assim.

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

Podemos chamar assim

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

Eu misturei as respostas até agora e adicionei a ela, porque eu tive que ler todas elas e investigar adicionalmente por um tempo para exibir uma string de data e hora do banco de dados no formato de fuso horário local de um usuário.

A string datetime vem de um banco de dados python/Django no formato: 2016-12-05T15: 12: 24.215Z

A detecção confiável da linguagem do navegador em JavaScript parece não funcionar em todos os navegadores (consulte JavaScript para detectar a preferência de idioma do navegador ), portanto, obtenho o idioma do navegador do servidor.

Python/Django: envie a linguagem do navegador de solicitação como parâmetro de contexto:

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

HTML: escreva em uma entrada oculta:

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

JavaScript: obtenha o valor da entrada oculta, por ex. pt-BR, pt-BR, q = 0.8, en; q = 0.6/e, em seguida, obtém o primeiro idioma da lista apenas por meio da expressão substituta e regular

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

JavaScript: converta para datetime e formate-o:

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

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

O resultado é (a linguagem do navegador é en-gb): 05/12/2016, 14:58

3
Anja

A melhor solução que encontrei é criar tags [time display = "llll" datetime = "UTC TIME" /] e usar javascript (jquery) para analisá-las e exibi-las em relação à hora do usuário.

http://momentjs.com/ Moment.js 

irá exibir o tempo bem.

2
Daniel

Você pode usar o seguinte, que informa o deslocamento do fuso horário do GMT em minutos: 

new Date().getTimezoneOffset();

Nota: - esta função retorna um número negativo.

2
dave

getTimeZoneOffset () e toLocaleString são bons para o trabalho de data básica, mas se você precisar de suporte a fuso horário real, veja o TimeZone.js do mde

Há mais algumas opções discutidas na resposta a this question

1
Aeon

Para converter data em data local, use o método toLocaleDateString ().

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

Para converter hora em hora local, use o método toLocaleTimeString ().

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