Erro no valor da data no início do horário de verão em determinados fusos horários
Aviso
O aplicativo da área de trabalho desativado e sem suporte do Internet Explorer 11 está programado para ser desativado permanentemente por meio de uma atualização do Microsoft Edge em certas versões do Windows 10. Para obter mais informações, consulte Perguntas frequentes sobre a desativação do aplicativo de área de trabalho do Internet Explorer 11.
Este artigo descreve o relatório de erros ao converter do horário padrão para o horário de verão (DST) e fornece uma solução.
Versão original do produto: Internet Explorer 11, Internet Explorer 10, Internet Explorer 9
Número original do KB: 2410734
Quando você usa o JavaScript Date
objeto para calcular datas em determinadas circunstâncias, os usuários podem ver resultados aparentemente incorretos. Esse comportamento ocorre quando as seguintes condições são verdadeiras:
- O fuso horário configurado em Configurações de data e hora faz a transição do horário padrão para o horário de verão à meia-noite.
- A aritmética de data usa
Date
objetos sem horas e minutos (ou horas e minutos usando 0) e usa apenas datas que fazem a transição do horário padrão para o horário de verão.
Por exemplo, tentar construir uma data de 17/10/2010 produz uma data de 16/10:
var dt = new Date(2010, 9,17);
// ...
console.log(dt.toString()); // evaluates to 'Sat Oct 16 23:00:00 UTC-0300 2010'
dt.getDate(); // evaluates to 16
Essa é uma instância específica de um problema que ocorre quando um Date()
objeto é inicializado exatamente para o horário em que o horário de verão começa.
Os valores usados para construir o objeto representam um tempo após o ponto em que o horário padrão termina, mas antes do que um relógio local mostraria após o início do Date
horário de verão. A especificação da linguagem ECMAScript (European Computer Manufacturers Association) especifica que um ajuste de horário de verão de 1 hora é subtraído ao calcular o valor de tempo, a representação interna do Date
objeto. No entanto, isso acaba representando um tempo antes do início do horário de verão. No caso do Brasil, isso ocorre à meia-noite e, portanto, o Date
objeto acaba representando uma hora do dia anterior.
Esse comportamento está em conformidade com o padrão ECMAScript e, portanto, é por design.
Quando você está preocupado apenas com o dia, mês e ano, pode contornar esse comportamento construindo objetos de data usando um valor de horas que não seja zero, ou seja, um valor de horas que seja seguramente maior do que o ajuste do horário de verão.
O padrão ECMAScript pode ser encontrado em ECMAScript® 2016 Language Specification.
A Seção 20.3.2 define como o construtor Date é interpretado, incluindo o fato de uma conversão de um valor de tempo para UTC (Tempo Universal Coordenado).
A seção 20.3.1.10 define as conversões entre a hora local e a hora UTC e afirma que essas conversões não são necessariamente inversas umas das outras.
A fórmula para esta conversão é a seguinte:
UTC( t ) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)
Se você seguir isso para o início do horário de verão, poderá ver como a hora é subtraída. Este exemplo é para o horário do Pacífico, portanto, a data real não é alterada. Comece com:
t = <Sun Mar 13 02:00:00 Pacific 2011>
LocalTZA = -8
The expression t - LocalTZA occurs twice in this equation; it evaluates to <Sun Mar 13 10:00:00 UTC 2011>. This is the exact moment when DST starts in the Pacific time zone. This is the key fact during conversion of this time to UTC:
UTC( <Sun Mar 13 02:00:00 Pacific 2011> )
= <Sun Mar 13 02:00:00 Pacific 2011> - LocalTZA - DaylightSavingTA( <Sun Mar 13 02:00:00 Pacific 2011> - LocalTZA )
= <Sun Mar 13 10:00:00 UTC 2011> -DaylightSavingTA( <Sun Mar 13 10:00:00 UTC 2011> )
= <Sun Mar 13 10:00:00 UTC 2011>- 1
= <Sun Mar 13 9:00:00 UTC 2011>