Como verificar se o DST (Horário de verão) está em vigor e se é o que é o deslocamento?

Este é um pouco do meu código JS para o qual isso é necessário:

var secDiff=Math.abs(Math.round((utc_date-this.premiere_date)/1000)); this.years=this.calculateUnit(secDiff,(86400*365)); this.days=this.calculateUnit(secDiff-(this.years*(86400*365)),86400); this.hours=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)),3600); this.minutes=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)),60); this.seconds=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)-(this.minutes*60)),1); 

Eu quero obter o datetime em atrás, mas se o DST estiver em uso, as datas serão desativadas em 1 hora. Não sei como verificar se o horário de verão está em uso ou não.

Como posso saber quando a hora de verão começa e termina?

Esse código usa o fato de que getTimezoneOffset retorna um valor maior durante o horário padrão versus o horário de verão (DST). Assim, ele determina a saída esperada durante a Hora Padrão e compara se a saída da data especificada é a mesma (Padrão) ou menor (DST).

Observe que getTimezoneOffset retorna números positivos de minutos para as zonas a oeste de UTC, que geralmente são declaradas como horas negativas (já que estão “atrás” de UTC). Por exemplo, Los Angeles é UTC – 8h Standard, UTC-7h DST. getTimezoneOffset retorna 480 (positivo 480 minutos) em dezembro (inverno, horário padrão), em vez de -480 . Ele retorna números negativos para o Hemisfério Oriental (como -600 para Sydney no inverno, apesar de estar “à frente” ( UTC + 10h ).

 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.isDstObserved = function () { return this.getTimezoneOffset() < this.stdTimezoneOffset(); } var today = new Date(); if (today.isDstObserved()) { alert ("Daylight saving time!"); } 

Crie duas datas: uma em junho, uma em janeiro. Compare seus valores getTimezoneOffset ().

  • if January offset> June offset, o cliente está no hemisfério norte
  • if January offset
  • se não houver diferença, o fuso horário do cliente não observa o horário de verão

Agora, verifique getTimezoneOffset () da data atual.

  • se igual a junho, hemisfério norte, o fuso horário atual é DST (+1 hora)
  • se igual a janeiro, hemisfério sul, o fuso horário atual é DST (+1 hora)

Eu enfrentei esse mesmo problema hoje, mas como a nossa economia de luz do dia começa e para em momentos diferentes dos EUA (pelo menos do meu ponto de vista), usei uma rota um pouco diferente.

 var arr = []; for (var i = 0; i < 365; i++) { var d = new Date(); d.setDate(i); newoffset = d.getTimezoneOffset(); arr.push(newoffset); } DST = Math.min.apply(null, arr); nonDST = Math.max.apply(null, arr); 

Em seguida, você simplesmente compara o deslocamento atual do fuso horário com DST e nonDST para ver qual corresponde.

Com base no comentário de Matt Johanson sobre a solução fornecida por Sheldon Griffin, criei o seguinte código:

  Date.prototype.stdTimezoneOffset = function() { var fy=this.getFullYear(); if (!Date.prototype.stdTimezoneOffset.cache.hasOwnProperty(fy)) { var maxOffset = new Date(fy, 0, 1).getTimezoneOffset(); var monthsTestOrder=[6,7,5,8,4,9,3,10,2,11,1]; for(var mi=0;mi<12;mi++) { var offset=new Date(fy, monthsTestOrder[mi], 1).getTimezoneOffset(); if (offset!=maxOffset) { maxOffset=Math.max(maxOffset,offset); break; } } Date.prototype.stdTimezoneOffset.cache[fy]=maxOffset; } return Date.prototype.stdTimezoneOffset.cache[fy]; }; Date.prototype.stdTimezoneOffset.cache={}; Date.prototype.isDST = function() { return this.getTimezoneOffset() < this.stdTimezoneOffset(); }; 

Ele tenta obter o melhor de todos os mundos, levando em conta todos os comentários e respostas sugeridas anteriormente e especificamente:

1) Armazena em cache o resultado por ano de stdTimezoneOffset para que você não precise recalculá-lo ao testar várias datas no mesmo ano.

2) Não pressupõe que o DST (se existir) seja necessariamente em julho, e funcionará mesmo que em algum momento e em algum lugar seja em qualquer mês. No entanto, em termos de desempenho, ele funcionará mais rápido se, de fato, julho (ou quase meses) for realmente DST.

3) Caso pior, irá comparar o getTimezoneOffset do primeiro de cada mês. [e faça isso Uma vez por ano testado].

A suposição que ainda faz é que o período DST é maior que um único mês.

Se alguém quiser remover essa suposição, ele pode mudar o loop para algo mais parecido com o que está na solução fornecida por Aaron Cole - mas eu ainda iria saltar meio ano à frente e sair do circuito quando dois deslocamentos diferentes forem encontrados.]

Essa resposta é bem parecida com a resposta aceita, mas não substitui o protótipo Date e usa apenas uma chamada de function para verificar se o horário de verão está em vigor, em vez de dois.


A idéia é que, como nenhum país observa o DST que dura 7 meses [1] , em uma área que observa o horário de verão, a compensação do horário UTC em janeiro será diferente da de julho.

Enquanto o horário de verão move os relógios para frente , o JavaScript sempre retorna um valor maior durante o horário padrão. Portanto, obter o deslocamento mínimo entre janeiro e julho obterá o deslocamento do fuso horário durante o horário de verão.

Em seguida, verificamos se o fuso horário das datas é igual a esse valor mínimo. Se for, então estamos em DST; caso contrário, não somos.

A function a seguir usa esse algoritmo. Ele recebe um object de data, d , e retorna true se o horário de verão estiver em vigor para essa data e false se não for:

 function isDST(d) { let jan = new Date(d.getFullYear(),0,1).getTimeZoneOffet(); let jul = new Date(d.getFullYear(),6,1).getTimeZoneOffet(); return Math.min(jan,jul) == d.getTimezoneOffset(); } 

A biblioteca moment.js fornece um método .isDst() em seus objects de tempo.

momento # isDST verifica se o momento atual está no horário de verão.

 moment([2011, 2, 12]).isDST(); // false, March 12 2011 is not DST moment([2011, 2, 14]).isDST(); // true, March 14 2011 is DST 

Você está perto, mas um pouco fora. Você nunca precisa calcular seu próprio tempo, pois é o resultado de seu próprio relógio. Ele pode detectar se você está usando o horário de verão em seu local, mas não para um local remoto produzido pelo deslocamento:

 newDateWithOffset = new Date(utc + (3600000*(offset))); 

Isso ainda estará errado e fora de uma hora se estiverem no horário de verão. Você precisa de uma conta de tempo remoto se eles estiverem dentro do horário de verão ou não e ajustar de acordo. tente calcular isso e mudar o relógio para – digamos, 2/1/2015 e redefinir o relógio de volta uma hora como se estivesse fora do horário de verão. Em seguida, calcule para um deslocamento para um local que ainda deve estar duas horas atrasado. Ele mostrará uma hora à frente da janela de duas horas. Você ainda precisa contabilizar a hora e ajustar. Eu fiz isso para NY e Denver e sempre vou a incorreta (hora à frente) em Denver.

Recentemente, precisei criar uma string de data com UTC e DST e, com base na resposta de Sheldon, juntei isso:

 Date.prototype.getTimezone = function(showDST) { var jan = new Date(this.getFullYear(), 0, 1); var jul = new Date(this.getFullYear(), 6, 1); var utcOffset = new Date().getTimezoneOffset() / 60 * -1; var dstOffset = (jan.getTimezoneOffset() - jul.getTimezoneOffset()) / 60; var utc = "UTC" + utcOffset.getSign() + (utcOffset * 100).preFixed(1000); var dst = "DST" + dstOffset.getSign() + (dstOffset * 100).preFixed(1000); if (showDST) { return utc + " (" + dst + ")"; } return utc; } Number.prototype.preFixed = function (preCeiling) { var num = parseInt(this, 10); if (preCeiling && num < preCeiling) { num = Math.abs(num); var numLength = num.toString().length; var preCeilingLength = preCeiling.toString().length; var preOffset = preCeilingLength - numLength; for (var i = 0; i < preOffset; i++) { num = "0" + num; } } return num; } Number.prototype.getSign = function () { var num = parseInt(this, 10); var sign = "+"; if (num < 0) { sign = "-"; } return sign; } document.body.innerHTML += new Date().getTimezone() + "
"; document.body.innerHTML += new Date().getTimezone(true);
 

Output for Turkey (UTC+0200) and currently in DST:   UTC+0300 (DST+0100)


Descobri que usar a biblioteca Moment.js com alguns dos conceitos descritos aqui (comparando janeiro a junho) funciona muito bem.

Essa function simples retornará se o fuso horário no qual o usuário está observa o horário de verão:

 function HasDST() { return moment([2017, 1, 1]).isDST() != moment([2017, 6, 1]).isDST(); } 

Uma maneira simples de verificar se isso funciona (no Windows) é alterar seu fuso horário para uma zona não DST, por exemplo, o Arizona retornará false, enquanto EST ou PST retornará true.

insira a descrição da imagem aqui

O método getTimezoneOffset() em JavaScript, em um navegador, retorna o número de minutos de deslocamento do fuso horário 00:00. Por exemplo, o fuso horário America / New_York em Daylight Savings (DST) retorna o número 300. 300 minutos é 5 horas de diferença de zero. 300 minutos divididos por 60 minutos é de 5 horas. Cada fuso horário é comparado ao fuso horário zero, +00: 00 / Etc / GMT / horário de Greenwich.

Documento Web do MDN

A próxima coisa que você deve saber é que o deslocamento tem o sinal oposto do fuso horário real.

As informações sobre fusos horários são mantidas pela Autoridade de Atribuição de Números da Internet (iana)

fusos horários iana

Uma tabela bem formatada de fusos horários é fornecida por joda.org

fusos horários

+00: 00 ou Etc / GMT é o horário de Greenwich

Todos os fusos horários são compensados ​​de +00: 00 / “Etc / GMT” / horário de Greenwich

O horário de verão é sempre um horário anterior ao horário “regular” no verão. Você ajusta seus relógios de volta no outono. (“Fall Back” slogan para lembrar o que fazer)

Assim, o horário America / New_York em Daylight Savings (inverno) é uma hora antes do horário normal. Então, por exemplo, o que normalmente era 17h da tarde na cidade de Nova York no verão, agora são 4h da América / New_York em Daylight Savings. O nome “America / New_York” hora é um nome de fuso horário “Long Format”. A costa leste dos EUA normalmente chama seu fuso horário de horário do leste dos EUA (EST)

Se você quiser comparar o deslocamento de fuso horário de hoje com o deslocamento de fuso horário de alguma outra data, você precisa saber que o sinal matemático (+/- “Positivo / Negativo”) do deslocamento do fuso horário é o oposto do fuso horário.

Olhe para a tabela de fuso horário em joda.org e encontre o fuso horário para “America / New_York”. Ele terá um sinal negativo na frente do Standard Offset.

A terra gira no sentido anti-horário em seu eixo. Uma pessoa observa o nascer do sol em Greenwich e vê o nascer do sol 5 horas antes que alguém na cidade de Nova York veja o nascer do sol. E alguém na Costa Oeste dos EUA verá o nascer do sol depois que alguém na Costa Leste dos EUA vir o nascer do sol.

Há uma razão pela qual você precisa saber tudo isso. Assim, você poderá determinar logicamente se algum código JavaScript está obtendo o status do horário de verão corretamente ou não, sem precisar testar todos os fusos horários em diferentes períodos do ano.

Imagine que é novembro em Nova York e os relógios foram atrasados ​​uma hora. No verão em Nova York, o deslocamento é de 240 minutos ou 4 horas.

Você pode testar isso criando uma data em julho e, em seguida, obtendo o deslocamento.

 var July_Date = new Date(2017, 6, 1); var july_Timezone_OffSet = July_Date.getTimezoneOffset(); console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet) 

O que será impresso no log do console de ferramentas de desenvolvedor do navegador?

Resposta é: 240

Agora, você pode criar uma data em janeiro e ver o que seu navegador retorna para um deslocamento de fuso horário para a temporada de inverno.

 var Jan_Date = new Date(2017, 0, 1);//Month is zero indexed - Jan is zero var jan_Timezone_OffSet = Jan_Date.getTimezoneOffset(); console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet) 

A resposta é: 300

Obviamente, 300 é maior que 240. Então, o que isso significa? Você deve escrever um código que testa o deslocamento de inverno sendo maior que o deslocamento de verão? Ou o deslocamento de verão menor que o deslocamento de inverno? Se houver uma diferença entre as compensações de fuso horário no verão e no inverno, você poderá considerar que o horário de verão está sendo usado para esse fuso horário. Mas isso não diz se hoje está usando o horário de verão para o fuso horário dos navegadores. Então, você precisa obter o deslocamento de fuso horário para hoje.

 var today = new Date(); var todaysTimeZone = today.getTimezoneOffset(); console.log('todaysTimeZone : ' + todaysTimeZone) 

A resposta é: ? – Depende da época do ano

Se o deslocamento de fuso horário de hoje e o deslocamento do fuso horário de verão forem iguais, E se as compensações de fuso horário no verão e no inverno forem diferentes, então, por dedução lógica, hoje NÃO deve estar no DST.

Você pode omitir comparando as compensações de fuso horário de verão e inverno, (saber se o horário de verão é usado para esse fuso horário) e apenas comparar o deslocamento de fuso horário atual com o deslocamento de verão TZ e sempre obter a resposta correta?

 today's TZ Offset !== Summer TZ Offset 

Bem, hoje é no inverno ou no verão? Se você soubesse disso, poderia aplicar a seguinte lógica:

 if ( it_is_winter && ( todays_TZ_Offset !== summer_TZ_Offset) { var are_We_In_DST = true; } 

Mas o problema é que você não sabe se a data de hoje é no inverno ou no verão. Cada fuso horário pode ter suas próprias regras para quando o horário de verão é iniciado e interrompido. Você precisa acompanhar as regras de cada fuso horário para cada fuso horário do mundo. Então, se há uma maneira melhor e mais fácil, então você pode fazê-lo da maneira melhor e mais fácil.

O que nos resta é que você precisa saber se esse fuso horário usa DST e comparar o deslocamento de fuso horário de hoje com o deslocamento do fuso horário de verão. Isso sempre lhe dará uma resposta confiável.

A lógica final é:

 if ( DST_Is_Used_In_This_Time_Zone && ( todays_TZ_Offset !== summer_TZ_Offset) { var are_We_In_DST = true; } 

Função para determinar se o fuso horário no navegador usa DST:

 function is_DST_Used_In_This_TimeZone() { var Jan_Date, jan_Timezone_OffSet, July_Date, july_Timezone_OffSet offsetsNotEqual, thisYear, today; today = new Date();//Create a date object that is now thisYear = today.getFullYear();//Get the year as a number Jan_Date = new Date(thisYear, 0, 1);//Month is zero indexed - Jan is zero jan_Timezone_OffSet = Jan_Date.getTimezoneOffset(); console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet) July_Date = new Date(thisYear, 6, 1); july_Timezone_OffSet = July_Date.getTimezoneOffset(); console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet) offsetsNotEqual = july_Timezone_OffSet !== jan_Timezone_OffSet;//True if not equal console.log('offsetsNotEqual: ' + offsetsNotEqual); return offsetsNotEqual;//If the offsets are not equal for summer and //winter then the only possible reason is that DST is used for //this time zone } 
    Intereting Posts