Práticas recomendadas para horário de verão e fuso horário [fechado]


2046

Espero fazer desta pergunta e das respostas o guia definitivo para lidar com o horário de verão, em particular para lidar com as mudanças reais.

Se você tiver algo a acrescentar, faça

Muitos sistemas dependem de manter a hora exata, o problema está nas alterações de hora devido ao horário de verão - avançar ou retroceder o relógio.

Por exemplo, há regras de negócios em um sistema de recebimento de pedidos que depende da hora do pedido - se o relógio mudar, as regras podem não ser tão claras. Como o tempo do pedido deve ser mantido? É claro que há um número infinito de cenários - este é simplesmente um exemplo.

  • Como você lidou com a questão do horário de verão?
  • Que suposições fazem parte da sua solução? (procurando o contexto aqui)

Tão importante, se não mais:

  • O que você tentou que não funcionou?
  • Por que não funcionou?

Eu estaria interessado em programação, SO, persistência de dados e outros aspectos pertinentes do problema.

As respostas gerais são ótimas, mas eu também gostaria de ver detalhes, especialmente se elas estiverem disponíveis apenas em uma plataforma.


2
@abatishchev - dessa maneira GETDATE()no SQL será UTC (como será DateTime.Now). E o servidor não será afetado por nenhum tipo de alteração automática do horário de verão.
Oded

4
@Oded: posso concordar se "no servidor" será adicionado. Mas isso ainda pode afetar outros aplicativos que precisam da hora local. Por esse e outros motivos, acho melhor solicitar tempo Utc explicitamente.
precisa saber é o seguinte

7
O UTC é preferível ao GMT, tanto porque ele é definido com mais precisão quanto porque as definições GMT são confusas em alguns sistemas operacionais. É comum as pessoas tratarem os termos "GMT" e "UTC" como intercambiáveis, mas eles não são inteiramente. Para praticamente qualquer finalidade de software / sistema, use o UTC. Veja stackoverflow.com/questions/2292334/…
Chris Johnson

7
@ JoshStodola - ' resposta ' de Jon Skeet .
Kenny Evitt

1
@Oded você não pode assumir que o servidor estará no UTC, eu vi servidores de produção em que o fuso horário era "UTC", mas tinha o horário de verão aplicado, então na verdade era UTC + 1 por mais da metade do ano. Concordo com @abatishchev ser explícito e uso DateTime.UtcNowe GETUTCDATE(), também mostra outros devs que você realmente pensei sobre isso
ono2012

Respostas:


940

Resumo das respostas e outros dados: (adicione o seu)

Faz:

  • Sempre que você estiver se referindo a um momento exato no tempo, persista o tempo de acordo com um padrão unificado que não é afetado pelo horário de verão. (GMT e UTC são equivalentes a esse respeito, mas é preferível usar o termo UTC. Observe que o UTC também é conhecido como horário Zulu ou Z. )
  • Se você optar por persistir um horário usando um valor de horário local, inclua o deslocamento de horário local para esse horário específico do UTC (esse deslocamento pode mudar ao longo do ano), para que o carimbo de data e hora possa ser interpretado sem ambiguidade mais tarde.
  • Em alguns casos, pode ser necessário para armazenar tanto a hora UTC e a hora local equivalente. Geralmente, isso é feito com dois campos separados, mas algumas plataformas suportam um datetimeoffsettipo que pode armazenar os dois em um único campo.
  • Ao armazenar registros de data e hora como um valor numérico, use a hora do Unix - que é o número de segundos inteiros desde1970-01-01T00:00:00Z (excluindo segundos bissextos). Se você precisar de maior precisão, use milissegundos. Este valor deve sempre ser baseado no UTC, sem nenhum ajuste de fuso horário.
  • Se você precisar modificar posteriormente o carimbo de data e hora, inclua o ID do fuso horário original para determinar se o deslocamento pode ter sido alterado em relação ao valor original registrado.
  • Ao agendar eventos futuros, geralmente a hora local é preferida ao invés do UTC, pois é comum que o deslocamento seja alterado. Ver resposta e postagem no blog .
  • Ao armazenar datas inteiras, como aniversários e aniversários, não converta para UTC ou qualquer outro fuso horário.
    • Quando possível, armazene em um tipo de dados somente para data que não inclua uma hora do dia.
    • Se esse tipo não estiver disponível, sempre ignore a hora do dia ao interpretar o valor. Se você não tiver certeza de que a hora do dia será ignorada, escolha 12:00 ao meio-dia, em vez de 00:00 Meia-noite como um horário representativo mais seguro nesse dia.
  • Lembre-se de que as compensações de fuso horário nem sempre são um número inteiro de horas (por exemplo, o horário padrão indiano é UTC + 05: 30 e o Nepal usa UTC + 05: 45).
  • Se estiver usando Java, use java.time para Java 8 e posterior.
  • Se estiver usando o .NET , considere usar o Noda Time .
  • Se estiver usando o .NET sem o Noda Time, considere que DateTimeOffsetgeralmente é uma escolha melhor que DateTime.
  • Se você estiver usando Perl, use DateTime .
  • Se você estiver usando Python, use pytz ou dateutil .
  • Se estiver usando JavaScript, use moment.js com a extensão moment-timezone .
  • Se estiver usando PHP> 5.2, use as conversões de fuso horário nativo fornecidas por DateTimee DateTimeZoneclasses. Tenha cuidado ao usar DateTimeZone::listAbbreviations()- veja a resposta . Para manter o PHP atualizado com os dados do Olson, instale periodicamente o pacote PECL com fuso horário ; veja a resposta .
  • Se estiver usando C ++, certifique-se de usar uma biblioteca que use os implementos apropriados no banco de dados de fuso horário da IANA . Isso inclui cctz , ICU e a biblioteca "tz" de Howard Hinnant .
    • Não use o Boost para conversões de fuso horário. Embora sua API afirme oferecer suporte a identificadores padrão da IANA (também conhecidos como "zoneinfo"), ela os mapeia de maneira grosseira para dados no estilo POSIX, sem considerar o rico histórico de alterações que cada zona pode ter. (Além disso, o arquivo ficou sem manutenção.)
  • Se estiver usando o Rust, use o cronógrafo .
  • A maioria das regras de negócios usa horário civil, em vez de UTC ou GMT. Portanto, planeje converter os carimbos de data / hora UTC em um fuso horário local antes de aplicar a lógica do aplicativo.
  • Lembre-se de que os fusos horários e as compensações não são fixos e podem mudar. Por exemplo, historicamente os EUA e o Reino Unido usaram as mesmas datas para "avançar" e "recuar". No entanto, em 2007, os EUA mudaram as datas em que os relógios foram alterados. Isso agora significa que, durante 48 semanas do ano, a diferença entre o horário de Londres e o de Nova York é de 5 horas e, durante 4 semanas (3 na primavera, 1 no outono), são 4 horas. Esteja ciente de itens como este em qualquer cálculo que envolva várias zonas.
  • Considere o tipo de hora (hora real do evento, hora de transmissão, hora relativa, hora histórica, hora recorrente) que elementos (carimbo de data / hora, deslocamento do fuso horário e nome do fuso horário) você precisa armazenar para obter uma recuperação correta - consulte "Tipos de hora" em esta resposta .
  • Mantenha os arquivos tzdata do SO, do banco de dados e do aplicativo sincronizados, entre si e o resto do mundo.
  • Nos servidores, defina os relógios de hardware e OS como UTC em vez de um fuso horário local.
  • Independentemente do item anterior, o código do servidor, incluindo sites, nunca deve esperar que o fuso horário local do servidor seja algo em particular. ver resposta .
  • Prefira trabalhar com fusos horários caso a caso no código do aplicativo, em vez de globalmente através de configurações ou padrões do arquivo de configuração.
  • Use NTP serviços em todos os servidores.
  • Se estiver usando o FAT32 , lembre-se de que os carimbos de data e hora são armazenados no horário local, não no UTC.
  • Ao lidar com eventos recorrentes (programa semanal de TV, por exemplo), lembre-se de que o horário muda com o horário de verão e será diferente entre os fusos horários.
  • Sempre consulte valores de data e hora como incluso no limite inferior, exclusivo no limite superior ( >=, <).

Não faça:

  • Não confunda um "fuso horário", como America/New_Yorkum "deslocamento de fuso horário", como -05:00. São duas coisas diferentes. Veja o wiki da etiqueta de fuso horário .
  • Não use o Dateobjeto JavaScript para executar cálculos de data e hora em navegadores da web mais antigos, pois o ECMAScript 5.1 e inferior têm uma falha de design que pode usar o horário de verão incorretamente. (Isso foi corrigido no ECMAScript 6/2015).
  • Nunca confie no relógio do cliente. Pode muito bem estar incorreto.
  • Não diga às pessoas para "sempre usar o UTC em qualquer lugar". Este conselho geral é míope de vários cenários válidos descritos anteriormente neste documento. Em vez disso, use a referência de tempo apropriada para os dados com os quais você está trabalhando. (O registro de data e hora pode usar UTC, mas os valores futuros de agendamento de horário e somente data não devem.)

Teste:

  • Ao testar, certifique-se de testar países no oeste, leste, norte e sul hemisférios (de fato em cada quarto do globo, portanto, quatro regiões), com o horário de verão em andamento e não (dá 8) e um país que faz isso. não use o horário de verão (outros 4 para cobrir todas as regiões, perfazendo 12 no total).
  • Teste a transição do horário de verão, ou seja, quando você está no horário de verão, selecione um valor de tempo no inverno.
  • Testar casos de limite, como um fuso horário UTC + 12, com horário de verão, tornando a hora local UTC + 13 no verão e até mesmo locais UTC + 13 no inverno
  • Teste todas as bibliotecas e aplicativos de terceiros e verifique se eles lidam com dados de fuso horário corretamente.
  • Teste os fusos horários de meia hora, pelo menos.

Referência:

De outros:

  • Faça lobby com seu representante para encerrar a abominação que é DST. Sempre podemos esperar ...
  • Lobby para o horário padrão da Terra

31
Usar o GMT realmente não resolve o problema, você ainda precisa descobrir qual é o delta certo a ser aplicado, e é aí que reside toda a complexidade. O delta pode ser complexo para determinar em sistemas usados ​​por usuários em diferentes regiões (com diferentes agendas de horário de verão) ou em sistemas que mostram dados históricos / futuros.
ckarras

10
Isso é verdade se tudo o que o aplicativo precisa fazer é exibir a hora local atual. Mas se tivermos, por exemplo, um servidor na Austrália que precisa exibir a data / hora de uma transação no Canadá em 2 de abril de 2006 (este foi o último ano antes das regras de troca de horário de verão serem alteradas no Canadá) - você tem uma chamada do SO que pode fazer DateTime ("2006/04/02 14: 35Z"). ToLocalTime (). WithDaylightSavingRules ("Canada", 2006)?
ckarras

22
Sim, existe uma chamada do sistema operacional no Windows - SystemTimeToTzSpecificLocation. msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx
Michael Madsen

7
@tchrist Talvez, se você for persistente, possa.
Peter Ajtai

16
Lembre-se de que, ao converter datas futuras (até amanhã) para o UTC, você sempre perde algo. Por exemplo, você usou algum deslocamento conhecido para fazer essa conversão, mas como a data é futura, sempre há uma chance de o grupo que definir essas regras alterá-las. Além disso, é virtualmente impossível converter algumas datas futuras em UTC porque os horários de verão não são conhecidos até aquele ano (alguns países definem as datas todos os anos, não mais de 10 anos à frente ou com base em regras definidas).
eselk

319

Não tenho certeza do que posso adicionar às respostas acima, mas aqui estão alguns pontos:

Tipos de tempos

Há quatro momentos diferentes que você deve considerar:

  1. Hora do evento: por exemplo, a hora em que um evento esportivo internacional acontece, ou uma coroação / morte / etc. Isso depende do fuso horário do evento e não do visualizador.
  2. Horário da televisão: por exemplo, um programa de TV específico é transmitido às 21h, horário local, em todo o mundo. Importante ao pensar em publicar os resultados (por exemplo, American Idol) em seu site
  3. Tempo relativo: por exemplo: Esta pergunta tem uma recompensa aberta em 21 horas. É fácil de exibir
  4. Hora recorrente: por exemplo: um programa de TV é exibido toda segunda-feira às 21:00, mesmo quando o horário de verão é alterado.

Há também horário histórico / alternativo. Isso é irritante porque pode não ser mapeado de volta ao horário padrão. Por exemplo: datas julianas, datas de acordo com o calendário lunar de Saturno, o calendário klingon.

O armazenamento de registros de data e hora de início / fim no UTC funciona bem. Para 1, você precisa de um nome de fuso horário do evento + deslocamento armazenado junto com o evento. Para o 2, você precisa de um identificador de horário local armazenado em cada região e um nome de fuso horário local + deslocamento armazenado para todos os visualizadores (é possível derivar isso do IP se você estiver em uma crise). Para 3, armazene em segundos UTC e não há necessidade de fusos horários. 4 é um caso especial de 1 ou 2, dependendo se é um evento global ou local, mas você também precisa armazenar um evento criado em registro de data e hora para saber se uma definição de fuso horário foi alterada antes ou depois da criação deste evento. Isso é necessário se você precisar mostrar dados históricos.

Tempos de armazenamento

  • Sempre armazene a hora no UTC
  • Converter para hora local em exibição (local sendo definido pelo usuário que está olhando para os dados)
  • Ao armazenar um fuso horário, você precisa do nome, carimbo de data e hora e deslocamento. Isso é necessário porque, às vezes, os governos alteram o significado de seus fusos horários (por exemplo: o governo dos EUA alterou as datas de horário de verão) e seu aplicativo precisa lidar com as coisas normalmente ... mudou.

Compensações e nomes

Um exemplo do acima seria:

O jogo das finais da copa do mundo de futebol aconteceu na África do Sul (UTC + 2 - SAST) em 11 de julho de 2010 às 19:00 UTC.

Com essas informações, podemos determinar historicamente o horário exato em que as finais do WCS de 2010 ocorreram, mesmo que a definição de fuso horário na África do Sul mude, e poder exibi-lo aos espectadores no fuso horário local no momento em que consultam o banco de dados.

Hora do sistema

Você também precisa manter os arquivos tzdata do SO, do banco de dados e do aplicativo em sincronia, entre si e com o resto do mundo, e fazer testes extensivos ao atualizar. Não é novidade que um aplicativo de terceiros do qual você depende não lidou com uma alteração de TZ corretamente.

Verifique se os relógios de hardware estão definidos como UTC e, se você estiver executando servidores em todo o mundo, verifique se os SOs também estão configurados para usar o UTC. Isso se torna aparente quando você precisa copiar arquivos de log apache com rotação horária de servidores em vários fusos horários. Classificá-los por nome de arquivo só funciona se todos os arquivos tiverem o mesmo fuso horário. Isso também significa que você não precisa fazer cálculos de datas em sua cabeça quando muda de uma caixa para outra e precisa comparar os registros de data e hora.

Além disso, execute o ntpd em todas as caixas.

Clientes

Nunca confie no carimbo de data e hora obtido de uma máquina cliente como válido. Por exemplo, a data: cabeçalhos HTTP ou uma Date.getTime()chamada javascript . Isso é bom quando usado como identificadores opacos ou ao fazer cálculos de datas durante uma única sessão no mesmo cliente, mas não tente fazer referência cruzada desses valores com algo que você possui no servidor. Seus clientes não executam NTP e podem não ter necessariamente uma bateria funcionando para o relógio do BIOS.

Curiosidades

Finalmente, os governos às vezes fazem coisas muito estranhas:

O horário padrão na Holanda era exatamente 19 minutos e 32,13 segundos à frente da UTC por lei, de 1909-05-01 a 1937-06-30. Este fuso horário não pode ser representado exatamente usando o formato HH: MM.

Ok, acho que terminei.


6
Esta resposta tem alguns pontos positivos. Gostaria especialmente de destacar esta parte "Hora recorrente: por exemplo: um programa de TV é exibido toda segunda-feira às 21:00, mesmo quando o horário de verão muda" O armazenamento de horários no UTC no banco de dados e a conversão para exibição ajuda muitos dos aspectos complicados de lidar com fusos horários. No entanto, lidar com "eventos recorrentes" que atravessam barreiras de horário de verão se torna muito mais difícil.
Jared Hales

45
+1 para as curiosidades. Mantendo o interessante conteúdo torna esta tarefa mais agradável, o que pode levar ao aumento da produtividade :)
Chris

4
Muitas coisas boas nesta resposta, mas algumas questões. 1) Muitas abreviações de fuso horário são ambíguas. veja aqui 2) Nem sempre você deseja armazenar no UTC. Na maioria das vezes - sim, mas o contexto é importante. Nos seus termos, o horário da televisão não seria armazenado no UTC. Além disso, às vezes é ilegal ou ilegal a política de não armazenar a hora local - e é aí que coisas como DateTimeOffset(ou equivalente) são úteis. Caso contrário, escreva bem.
precisa

1
Portanto, todos concordam que a biblioteca Joda é de longe a melhor ferramenta disponível para o trabalho. No entanto, precisamos manter a atualização (reconstrução) do arquivo jar JODA conforme este artigo ( joda.org/joda-time/tz_update.html ) para manter-se atualizado com as informações mais recentes do fuso horário. Existe alguma maneira padrão de baixar os dados mais recentes do fuso horário no site da IANA ( iana.org/time-zones ) e reconstruir a biblioteca joda? Em outras palavras, é possível automatizar esse processo em vez de fazê-lo manualmente?
saravana_pc

2
As curiosidades holandesas parecem legítimas. ietf.org/rfc/rfc3339.txt seção 5.8. No meio do caminho, imaginei que alguém estava puxando nossa perna.
Ruffin

89

Esta é uma questão importante e surpreendentemente difícil. A verdade é que não existe um padrão completamente satisfatório para o tempo persistente. Por exemplo, o padrão SQL e o formato ISO (ISO 8601) claramente não são suficientes.

Do ponto de vista conceitual, geralmente se lida com dois tipos de dados de data e hora, e é conveniente distingui-los (os padrões acima não o fazem): " tempo físico " e " tempo civil ".

Um instante "físico" do tempo é um ponto na linha do tempo universal contínua com a qual a física lida (ignorando a relatividade, é claro). Este conceito pode ser adequadamente codificado - persistido no UTC, por exemplo (se você pode ignorar os segundos bissextos).

Um horário "civil" é uma especificação de data e hora que segue normas civis: um ponto de tempo aqui é totalmente especificado por um conjunto de campos de data e hora (Y, M, D, H, MM, S, FS) mais um TZ (especificação de fuso horário) (também um "calendário", na verdade; mas vamos supor que restringimos a discussão ao calendário gregoriano). Um fuso horário e um calendário permitem conjuntamente (em princípio) mapear de uma representação para outra. Mas os instantes de tempo civil e físico são tipos de magnitudes fundamentalmente diferentes e devem ser mantidos conceitualmente separados e tratados de maneira diferente (uma analogia: matrizes de bytes e cadeias de caracteres).

A questão é confusa porque falamos desses eventos de forma intercambiável e porque os tempos civis estão sujeitos a mudanças políticas. O problema (e a necessidade de distinguir esses conceitos) se torna mais evidente para eventos no futuro. Exemplo (retirado da minha discussão aqui .

John registra em seu calendário um lembrete para algum evento na data 2019-Jul-27, 10:30:00e hora , TZ = Chile/Santiago, (que compensou GMT-4, portanto, corresponde ao UTC 2019-Jul-27 14:30:00). Mas, algum dia no futuro, o país decide alterar a compensação da TZ para GMT-5.

Agora, quando chegar o dia ... esse lembrete deve ser acionado às

A) 2019-Jul-27 10:30:00 Chile/Santiago = UTC time 2019-Jul-27 15:30:00?

ou

B) 2019-Jul-27 9:30:00 Chile/Santiago = UTC time 2019-Jul-27 14:30:00?

Não existe uma resposta correta, a menos que se saiba o que John conceitualmente quis dizer quando disse ao calendário "Por favor, ligue-me para 2019-Jul-27, 10:30:00 TZ=Chile/Santiago".

Ele quis dizer "data civil" ("quando os relógios da minha cidade marcam 10:30")? Nesse caso, A) é a resposta correta.

Ou ele quis dizer um "instante físico do tempo", um ponto na linha contínua de tempo do nosso universo, por exemplo, "quando o próximo eclipse solar acontecer". Nesse caso, a resposta B) é a correta.

Algumas APIs de Data / Hora acertam essa distinção: entre elas, Jodatime , que é a base da próxima (terceira!) API Java DateTime (JSR 310).


1
Outro ponto a considerar, que não vi abordado nas APIs, é que, mesmo quando o tempo e o fuso horário são determinados, há pelo menos dois significados plausíveis para, por exemplo, "13: 00: 00EDT". Pode-se referir a algo que se sabe ter ocorrido às 13h, horário local, que se acredita ter sido o horário de verão do leste, ou algo que se sabe ter ocorrido no momento em que o horário do leste chegou às 13:00, que se acredita ocorreram em um local que observa o horário de verão oriental. Se alguém tiver muitos carimbos de data e hora em que as informações do fuso horário podem estar erradas (por exemplo, arquivos de câmera digital) ... #
297

1
... saber se elas refletem uma hora local precisa ou uma hora global pode ser importante para determinar como corrigi-las.
Supercat 29/13

3
Claramente, John quer A) porque as pessoas vão trabalhar às 8:30, independentemente do horário de verão ou do fuso horário. Se eles entrarem no horário de verão, eles trabalharão às 8h30, quando sairem do horário de verão e trabalharão às 8h30. Se o país decidir mudar para outro fuso horário, eles irão trabalhar às 8h30 do dia seguinte
Gianluca Ghettini 9/17

59

Faça uma separação arquitetural clara das preocupações - para saber exatamente qual camada interage com os usuários e precisa alterar a data / hora para / da representação canônica (UTC). A data e hora não UTC é a apresentação (segue o fuso horário local do usuário), a hora UTC é o modelo (permanece único para o backend e as camadas intermediárias).

Além disso, decida qual é o seu público real, o que você não precisa servir e aonde você define a linha . Não toque em agendas exóticas, a menos que você tenha clientes importantes e considere servidores separados voltados para o usuário apenas para essa região.

Se você puder adquirir e manter a localização do usuário, use a localização para conversão sistemática de data e hora (por exemplo, cultura .NET ou uma tabela SQL), mas forneça uma maneira para o usuário final escolher substituições, se a data e hora forem críticas para seus usuários.

Se houver obrigações de auditoria históricas envolvidas (como dizer exatamente quando Jo na AZ pagou uma fatura há 2 anos em setembro) , mantenha o UTC e a hora local para o registro (suas tabelas de conversão mudarão com o tempo).

Defina o fuso horário referencial para dados que vêm em massa - como arquivos, serviços da web etc. Digamos que a empresa da Costa Leste tenha um data center na CA - você precisa perguntar e saber o que eles usam como padrão em vez de assumir um ou outro.

Não confie em deslocamentos de fuso horário incorporados na representação textual da data e hora e não aceite analisá-los e segui-los. Em vez disso, sempre solicite que o fuso horário e / ou o fuso horário de referência tenham que ser explicitamente definidos . Você pode facilmente receber tempo com o deslocamento PST, mas o tempo é realmente EST, já que esse é o tempo de referência e os registros do cliente foram exportados apenas em um servidor que está no PST.


40

Você precisa conhecer o banco de dados Olson tz , disponível em ftp://elsie.nci.nih.gov/pub http://iana.org/time-zones/ . É atualizado várias vezes por ano para lidar com as mudanças de última hora, frequentemente (quando) e para alternar entre o inverno e o verão (horário padrão e horário de verão) em diferentes países do mundo. Em 2009, o último lançamento foi nos anos 2009; em 2010, era 2010n; em 2011, era 2011n; no final de maio de 2012, o lançamento era 2012c. Observe que há um conjunto de códigos para gerenciar os dados e os dados reais do fuso horário, em dois arquivos separados (tzcode20xxy.tar.gz e tzdata20xxy.tar.gz). Tanto o código quanto os dados são de domínio público.

Essa é a fonte dos nomes de fuso horário, como América / Los_Angeles (e sinônimos, como EUA / Pacífico).

Se você precisar acompanhar as diferentes zonas, precisará do banco de dados Olson. Como outras pessoas recomendaram, você também deseja armazenar os dados em um formato fixo - normalmente o UTC é o escolhido - junto com um registro do fuso horário no qual os dados foram gerados. Convém distinguir entre o deslocamento do UTC no horário e o nome do fuso horário; isso pode fazer a diferença mais tarde. Além disso, saber que atualmente é 2010-03-28T23: 47: 00-07: 00 (EUA / Pacífico) pode ou não ajudá-lo a interpretar o valor 2010-11-15T12: 30 - que provavelmente é especificado no PST ( Horário Padrão do Pacífico) em vez de PDT (Horário de Verão do Pacífico).

As interfaces padrão da biblioteca C não são terrivelmente úteis com esse tipo de coisa.


Os dados da Olson foram movidos, em parte porque o AD Olson se aposentará em breve e em parte porque houve um processo (agora demitido) contra os mantenedores por violação de direitos autorais. O banco de dados de fuso horário agora é gerenciado sob os auspícios da IANA , a Autoridade para atribuição de números da Internet, e há um link na primeira página para 'Banco de dados de fuso horário' . A lista de discussão é agora tz@iana.org; a lista anúncio é tz-announce@iana.org.


12
O banco de dados Olson também contém dados históricos , o que o torna particularmente útil para lidar com o horário de verão. Por exemplo, ele sabe que um valor UTC correspondente a 31 de março de 2000 nos EUA não está no horário de verão, mas um valor UTC correspondente a 31 de março de 2008 nos EUA.
Josh Kelley

3
O Consórcio Unicode mantém um mapeamento entre Olson IDs zona Tomé e IDs de fuso horário do Windows: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/...
Josh Kelley

Link atualizado para a página do Consórcio Unicode: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
Span

Onde é possível encontrar informações sobre a análise dos arquivos Olson? Eu quero compilá-lo em uma tabela db, mas não consigo descobrir como eu deveria ler os arquivos
Salatiel

@ gidireich: a principal informação é encontrada com os dados e não é fácil de entender. A documentação principal está na zic.8página de manual (ou zic.8.txt). Você precisará do tzcode2011i.tar.gzarquivo em vez de, ou também, o tzdata2011i.tar.gzarquivo para obter essas informações.
11136 Jonathan Leffler #

26

Em geral, inclua o deslocamento da hora local (incluindo o deslocamento do horário de verão) nos registros de data e hora armazenados: o UTC sozinho não é suficiente se você desejar exibir posteriormente o registro de data e hora no fuso horário original (e na configuração do horário de verão).

Lembre-se de que o deslocamento nem sempre é um número inteiro de horas (por exemplo, o horário padrão da Índia é UTC + 05: 30).

Por exemplo, os formatos adequados são uma tupla (tempo unix, deslocamento em minutos) ou ISO 8601 .


5
Para exibição, o deslocamento é perfeito. Se você deseja fazer alterações, o deslocamento ainda não é suficiente. Você também precisa conhecer o fuso horário, pois o novo valor pode exigir um deslocamento diferente.
precisa saber é o seguinte

23

Atravessar a fronteira do "tempo do computador" e do "tempo das pessoas" é um pesadelo. A principal é que não existe um padrão para as regras que regem os fusos horários e o horário de verão. Os países podem alterar suas regras de fuso horário e horário de verão a qualquer momento, e eles o fazem.

Alguns países, por exemplo, Israel, Brasil, decidem todos os anos quando devem ter seu horário de verão, por isso é impossível saber com antecedência quando (se) o horário de verão estará em vigor. Outros estabeleceram regras (ish) sobre quando o horário de verão está em vigor. Outros países não usam o horário de verão.

Os fusos horários não precisam ter diferenças de hora inteira em relação ao GMT. O Nepal é +5,45. Existem até fusos horários com +13. Isso significa que:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

são todos ao mesmo tempo, mas 3 dias diferentes!

Também não há um padrão claro sobre as abreviações para fusos horários e como elas mudam quando no horário de verão, para que você acabe com coisas assim:

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

O melhor conselho é ficar longe da hora local o máximo possível e seguir a UTC onde puder. Converta apenas para horários locais no último momento possível.

Ao fazer o teste, certifique-se de testar países nos hemisférios ocidental e oriental, com o horário de verão em andamento e não e um país que não use o horário de verão (6 no total).


Em relação a Israel - isso é meio verdade. Embora a hora da alteração do horário de verão não seja uma data específica no calendário juliano - existe uma regra baseada no calendário hebraico (houve uma alteração em 2014). De qualquer forma, a idéia geral está correta - essas coisas podem mudar de vez em quando
Yaron U.

1
Além disso, AST = Horário Padrão do Atlântico. Quanto aos 'melhores conselhos', está tudo bem como ponto de partida, mas você precisa ler o restante desta página e fazer uma pequena oração, e você pode acertar por um tempo.
DavidWalley

20

Para PHP:

A classe DateTimeZone no PHP> 5.2 já é baseada no Olson DB mencionado por outros, portanto, se você estiver fazendo conversões de fuso horário no PHP e não no DB, estará isento de trabalhar com os arquivos Olson (difíceis de entender).

No entanto, o PHP não é atualizado com a mesma frequência que o Olson DB; portanto, o uso de conversões de fuso horário do PHP pode deixar informações desatualizadas do horário de verão e influenciar a correção dos seus dados. Enquanto isso não se espera que aconteça com frequência, pode acontecer, e vai acontecer se você tem uma grande base de usuários em todo o mundo.

Para lidar com o problema acima, use o pacote pecl timezonedb . Sua função é atualizar os dados do fuso horário do PHP. Instale este pacote com a frequência atualizada. (Não tenho certeza se as atualizações deste pacote seguem exatamente as atualizações do Olson, mas parece que são atualizadas com uma frequência que é pelo menos muito próxima da frequência das atualizações do Olson.)


18

Se o seu design puder acomodá-lo, evite a conversão da hora local todos juntos!

Para alguns, isso pode parecer insano, mas pense no UX: os usuários processam datas próximas e relativas (hoje, ontem, segunda-feira seguinte) mais rapidamente do que as datas absolutas (09.09.17, sexta-feira, 17 de setembro) à primeira vista. E quando você pensa mais sobre isso, a precisão dos fusos horários (e DST) é mais importante quanto mais próxima a data now(), portanto, se você puder expressar datas / horários em um formato relativo por +/- 1 ou 2 semanas, o resto das as datas podem ser UTC e não importam muito para 95% dos usuários.

Dessa forma, você pode armazenar todas as datas no UTC e fazer as comparações relativas no UTC e simplesmente mostrar as datas UTC do usuário fora do seu Limite de data relativo.

Isso também pode se aplicar à entrada do usuário (mas geralmente de uma maneira mais limitada). Selecionar a partir de um menu suspenso que possui apenas {Ontem, Hoje, Amanhã, Segunda e próxima quinta-feira} é muito mais simples e fácil para o usuário do que um selecionador de datas. Os selecionadores de data são alguns dos componentes mais indutores de dor no preenchimento de formulários. É claro que isso não funcionará em todos os casos, mas você pode ver que é preciso apenas um design inteligente para torná-lo muito poderoso.


16

Embora eu não tenha tentado, uma abordagem aos ajustes de fuso horário que eu consideraria atraente seria a seguinte:

  1. Armazene tudo em UTC.

  2. Crie uma tabela TZOffsetscom três colunas: RegionClassId, StartDateTime e OffsetMinutes (int, em minutos).

Na tabela, armazene uma lista de datas e horas em que a hora local foi alterada e por quanto. O número de regiões na tabela e o número de datas dependerão de qual intervalo de datas e áreas do mundo você precisa apoiar. Pense nisso como se fosse uma data "histórica", mesmo que as datas devam incluir o futuro em algum limite prático.

Quando você precisar calcular a hora local de qualquer hora UTC, faça o seguinte:

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

Convém armazenar esta tabela em cache no seu aplicativo e usar o LINQ ou outro meio semelhante para fazer as consultas, em vez de acessar o banco de dados.

Esses dados podem ser destilados do banco de dados tz de domínio público .

Vantagens e notas de rodapé dessa abordagem:

  1. Nenhuma regra é inserida no código; você pode ajustar os deslocamentos para novas regiões ou períodos facilmente.
  2. Você não precisa oferecer suporte a todos os intervalos de datas ou regiões; pode adicioná-los conforme necessário.
  3. As regiões não precisam corresponder diretamente aos limites geopolíticos e, para evitar a duplicação de linhas (por exemplo, a maioria dos estados nos EUA processa o horário de verão da mesma maneira), você pode ter entradas amplas de RegionClass que se vinculam em outra tabela a listas mais tradicionais de estados, países etc.
  4. Para situações como os EUA, onde a data de início e término do horário de verão mudou nos últimos anos, é muito fácil lidar com isso.
  5. Como o campo StartDateTime também pode armazenar um horário, o horário de troca padrão das 02:00 é tratado com facilidade.
  6. Nem todo mundo usa um horário de verão de 1 hora. Isso lida com esses casos facilmente.
  7. A tabela de dados é multiplataforma e pode ser um projeto de código aberto separado que pode ser usado por desenvolvedores que usam praticamente qualquer plataforma de banco de dados ou linguagem de programação.
  8. Isso pode ser usado para compensações que nada têm a ver com fusos horários. Por exemplo, os ajustes de 1 segundo que ocorrem de tempos em tempos para ajustar a rotação da Terra, ajustes históricos para e dentro do calendário gregoriano etc.
  9. Como isso está em uma tabela de banco de dados, consultas de relatório padrão etc. podem tirar proveito dos dados sem uma viagem pelo código da lógica de negócios.
  10. Isso também controla as compensações de fuso horário, se você desejar, e pode até levar em conta casos históricos especiais em que uma região é atribuída a outro fuso horário. Tudo o que você precisa é de uma data inicial que atribua um deslocamento de fuso horário a cada região com uma data mínima de início. Isso exigiria a criação de pelo menos uma região para cada fuso horário, mas permitiria que você fizesse perguntas interessantes como: "Qual é a diferença no horário local entre Yuma, Arizona e Seattle, Washington, em 2 de fevereiro de 1989 às 05:00?" (Apenas subtraia um SUM () do outro).

Agora, a única desvantagem dessa abordagem ou de qualquer outra é que as conversões da hora local para GMT não sejam perfeitas, pois qualquer alteração no horário de verão que tenha um deslocamento negativo para o relógio repete uma determinada hora local. Receio que não haja uma maneira fácil de lidar com essa, que é uma das razões pelas quais os horários locais são más notícias.


8
Sua ideia de banco de dados já foi implementada como o Banco de Dados Olson. Embora o horário de verão crie uma sobreposição, a especificação do fuso horário específico pode ajudar a resolver o problema. 2:15 EST e 2:15 EDT são horas diferentes. Conforme observado em outras postagens que especificam o deslocamento, também resolve a ambiguidade.
BillThor

5
O grande problema de manter seu próprio banco de dados é mantê-lo atualizado. Olson e Windows são mantidos para você. Eu tive mais de um caso de ter transições de horário de verão ruins porque as tabelas estavam desatualizadas. Rasgá-los completamente e depender de uma estrutura ou banco de dados no nível do SO é muito mais confiável.
precisa

4
Não crie seu próprio banco de dados : conte sempre com a API do sistema!
98013 Alex

15

Recentemente, tive um problema em um aplicativo da Web em que, em um post-back do Ajax, o horário de retorno do código do servidor era diferente do horário de entrega.

Provavelmente, tinha a ver com meu código JavaScript no cliente que criou a data de postagem no cliente como string, porque o JavaScript estava se ajustando ao fuso horário e ao horário de verão, e em alguns navegadores o cálculo para quando aplicar o horário de verão parecia ser diferente do que nos outros.

No final, optei por remover os cálculos de data e hora inteiramente no cliente e postei de volta no meu servidor em uma chave inteira que foi traduzida para a data e hora no servidor, para permitir transformações consistentes.

Aprendi com isso: não use cálculos de data e hora do JavaScript em aplicativos da web, a menos que você absolutamente precise.


Javascript é executado na máquina cliente, não na máquina servidor. O datetime de base do Javascript é o datetime do cliente, não o datetime do servidor.
BalusC

Oi BalusC. Eu entendo isso (do meu post original: "script javacode no cliente que criou a data ..."). Meu problema era que determinadas máquinas clientes processavam o horário de verão de uma maneira e outras de outra. Por isso eu me mudei tudo isso do lado do servidor do processamento para evitar a estranheza navegador
Joon

@ Joon - e há bugs nas implementações de javascript que você não pode detectar ou permitir. Portanto, sim, nunca use cálculos de data ECMAScript do lado do cliente para coisas que importam (embora você possa fazer um bom trabalho de outra forma).
RobG

14

Eu bati isso em dois tipos de sistemas, “sistemas de planejamento de turnos (por exemplo, trabalhadores de fábrica)” e “sistemas de gerenciamento de dependências de gás)…

Os dias de 23 e 25 horas são difíceis de lidar, assim como os turnos de 8 horas que duram 7 ou 9 horas. O problema é que você descobrirá que cada cliente ou mesmo departamento do cliente possui regras diferentes que eles criaram (geralmente sem documentação) sobre o que fazem nesses casos especiais.

É melhor que algumas perguntas não sejam feitas aos clientes até que eles paguem pelo seu software "pronto para uso". É muito raro encontrar um cliente que pense sobre esse tipo de problema com antecedência ao comprar software.

Eu acho que em todos os casos, você deve registrar a hora no UTC e converter para / da hora local antes de armazenar a data / hora. No entanto, mesmo saber em qual horário está pode ser difícil com o fuso horário e o fuso horário.


6
Minha namorada, uma enfermeira, trabalha à noite e precisa escrever o fuso horário durante a transição do horário de verão. Por exemplo, 02:00 CST vs 02:00 CDT
Joe Phillips

1
Sim, isso é comum: quando você calcula uma média diária (civil), precisa lidar com os dias de 23, 24 ou 25 horas. Como conseqüência, quando você calcula adicionar 1 dia, não adiciona 24 horas ! Segundo, não tente criar seu próprio código de fuso horário; use apenas a API do sistema. E não se esqueça de atualizar cada sistema implantado para obter o banco de dados atualizado do fuso horário .
98013 Alex

12

Para a web, as regras não são tão complicadas ...

  • No lado do servidor, use UTC
  • No lado do cliente, use o Olson
    • Motivo: os desvios do UTC não são seguros para o horário de verão (por exemplo, Nova York é EST (UTC - 5 horas) parte do ano, EDT (UTC - 4 horas) no restante do ano).
    • Para determinar o fuso horário do lado do cliente, você tem duas opções:

O restante é apenas a conversão UTC / local usando as bibliotecas de data e hora do lado do servidor. Bom para ir...


2
Este é um bom conselho como ponto de partida, mas depende totalmente da aplicação. Isso pode ser bom para um site amigável, mas se houver algum aspecto legal / jurisdicional / financeiro em seu aplicativo que alguém possa processar (trabalhei em vários), isso é uma simplificação excessiva, porque existem diferentes tipos de ' time ', conforme observado em outras partes desta página.
DavidWalley

12

Quando se trata de aplicativos executados em um servidor , incluindo sites e outros serviços de back-end, a configuração de fuso horário do servidor deve ser ignorada pelo aplicativo.

O conselho comum é definir o fuso horário do servidor como UTC. Essa é realmente uma boa prática recomendada, mas existe como um curativo para aplicativos que não seguem outras práticas recomendadas. Por exemplo, um serviço pode estar gravando arquivos de log com registros de data e hora locais em vez de registros baseados em UTC, criando assim ambiguidades durante a transição de fallback do horário de verão. Definir o fuso horário do servidor como UTC corrigirá esse aplicativo. No entanto, a correção real seria que o aplicativo registrasse usando o UTC para começar.

O código do servidor, incluindo sites, nunca deve esperar que o fuso horário local do servidor seja algo em particular.

Em alguns idiomas, o fuso horário local pode se infiltrar facilmente no código do aplicativo. Por exemplo, o DateTime.ToUniversalTimemétodo no .NET será convertido do fuso horário local para UTC e a DateTime.Nowpropriedade retornará o horário atual no fuso horário local. Além disso, o Dateconstrutor em JavaScript usa o fuso horário local do computador. Existem muitos outros exemplos como este. É importante praticar a programação defensiva, evitando qualquer código que use a configuração de fuso horário local do computador.

Reserve usando o fuso horário local para o código do lado do cliente, como aplicativos de desktop, aplicativos móveis e JavaScript do lado do cliente.


11

Mantenha seus servidores configurados para UTC e verifique se todos eles estão configurados para ntp ou equivalente.

O UTC evita problemas de horário de verão e os servidores fora de sincronia podem causar resultados imprevisíveis que demoram um pouco para serem diagnosticados.


9

Tenha cuidado ao lidar com carimbos de data e hora armazenados no sistema de arquivos FAT32 - ele sempre persiste nas coordenadas de horário local (que incluem DST - consulte o artigo msdn ). Queimou-se nesse.


Ótimo ponto. O NTFS não tem esse problema, mas algumas pessoas ainda usam o FAT32 - especialmente em chaves USB.
precisa

7

Outra coisa, verifique se os servidores têm o patch atualizado de horário de verão aplicado.

Tivemos uma situação no ano passado, em que nossos tempos estavam constantemente fora de uma hora por um período de três semanas para usuários norte-americanos, mesmo usando um sistema baseado no UTC.

Acontece que no final foram os servidores. Eles só precisavam de um patch atualizado aplicado ( Windows Server 2003 ).


6

DateTimeZone::listAbbreviations()Saída do PHP

Este método PHP retorna uma matriz associativa que contém alguns fusos horários 'principais' (como CEST), que por si só contêm fusos horários 'geográficos' mais específicos (como Europa / Amsterdã).

Se você estiver usando esses fusos horários e suas informações de deslocamento / horário de verão, é extremamente importante realizar o seguinte:

Parece que todas as configurações diferentes de deslocamento / DST (incluindo configurações históricas) de cada fuso horário estão incluídas!

Por exemplo, Europa / Amsterdã pode ser encontrado seis vezes na saída desta função. Duas ocorrências (deslocamento 1172/4772) são para o tempo de Amsterdã usado até 1937; dois (1200/4800) são para o período usado entre 1937 e 1940; e dois (3600/4800) são para o tempo usado desde 1940.

Portanto, você não pode confiar nas informações de deslocamento / DST retornadas por esta função como atualmente corretas / em uso!

Se você quiser saber o deslocamento atual / DST de um determinado fuso horário, precisará fazer algo assim:

<?php
$now = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo $now->getOffset();
?>

5

Se você mantiver sistemas de banco de dados em execução com o DST ativo, verifique cuidadosamente se eles precisam ser desligados durante a transição no outono. O Mandy DBS (ou outros sistemas também) não gosta de passar o mesmo ponto no horário (local) duas vezes, o que é exatamente o que acontece quando você volta o relógio no outono. A SAP resolveu isso com uma solução alternativa (IMHO realmente interessante) - em vez de voltar o relógio, eles deixaram o relógio interno rodar na metade da velocidade normal por duas horas ...


4

Você está usando a estrutura .NET ? Nesse caso, deixe-me apresentar o tipo DateTimeOffset , adicionado ao .NET 3.5.

Essa estrutura contém a DateTimee um Offset ( TimeSpan), que especifica a diferença entre a DateTimeOffsetdata e hora da instância e o Tempo Universal Coordenado (UTC).

  • O DateTimeOffset.Nowmétodo estático retornará uma DateTimeOffset instância que consiste na hora atual (local) e no deslocamento local (conforme definido nas informações regionais do sistema operacional).

  • O DateTimeOffset.UtcNowmétodo estático retornará uma DateTimeOffsetinstância que consiste no horário atual no UTC (como se você estivesse em Greenwich).

Outros tipos votos são os de fuso horário e TimeZoneInfo classes.


Esta não é uma solução para o problema apresentado.
caradrye

4

Para aqueles que lutam com isso no .NET , veja se o uso DateTimeOffsete / ou TimeZoneInfovale a pena.

Se você deseja usar os fusos horários da IANA / Olson ou considerar os tipos internos insuficientes para suas necessidades, consulte o Noda Time , que oferece uma API de data e hora muito mais inteligente para .NET.


4

As regras de negócios sempre devem funcionar em horário civil (a menos que haja legislação que diga o contrário). Esteja ciente de que o tempo civil é uma bagunça, mas é o que as pessoas usam, por isso é importante.

Internamente, mantenha os registros de data e hora em algo como segundos do tempo civil da época. A época não importa particularmente (eu prefiro a época do Unix ), mas torna as coisas mais fáceis do que a alternativa. Finja que os segundos bissextos não existem, a menos que você esteja fazendo algo que realmente precise deles (por exemplo, rastreamento por satélite). O mapeamento entre os carimbos de data e hora e o horário exibido é o único ponto em que as regras de horário de verão devem ser aplicadas; as regras mudam com freqüência (em nível global, várias vezes ao ano; culpe os políticos), portanto, certifique-se de não codificar o mapeamento. O banco de dados TZ da Olson é inestimável.


3
O problema aqui é que o horário civil (também conhecido como horário do calendário) não representa adequadamente um único momento no tempo. Se você adotar a abordagem dos segundos após a época, será realmente responsável por cada momento que foi pulado ou rebobinado pelas transições do horário de verão? Provavelmente não. A base de época funciona apenas contra o UTC ou alguma outra referência de tempo instantâneo fixa.
precisa saber é o seguinte

@MattJohnson Daí a parte "regras de negócios". Se as regras dizem que algo acontece às 2:30 da manhã (ou a qualquer momento), isso acontece duas vezes em um dia por ano e nunca em um dia por ano. É isso que o cliente espera que aconteça se não esclarecer a regra.
user253751

Manter timestamps internos em tempo civil pode ser muito complicado. Mantendo-o como segundos desde que uma época é ainda mais complicada, eu diria absolutamente perigoso. Tenho certeza de que há pessoas fazendo isso, e pode ser possível fazê-lo funcionar corretamente na maioria das vezes, se você for super cuidadoso, mas isso não pode ser considerado uma prática recomendada ou uma recomendação geral.
Steve Summit

2

Só queria apontar duas coisas que parecem imprecisas ou pelo menos confusas:

Sempre persista o tempo de acordo com um padrão unificado que não é afetado pelo horário de verão. GMT e UTC foram mencionados por pessoas diferentes, embora o UTC pareça ser mencionado com mais frequência.

Para (quase) todas as finalidades práticas de computação, o UTC é, de fato, GMT. A menos que você veja um registro de data e hora com um segundo fracionário, você está lidando com o GMT, o que torna essa distinção redundante.

Inclua o deslocamento da hora local como está (incluindo o deslocamento do horário de verão) ao armazenar registros de data e hora.

Um registro de data e hora é sempre representado no GMT e, portanto, não tem deslocamento.


1
O deslocamento da hora local permitirá recriar a "hora da parede" original do evento. Se você não armazenar esse campo adicional, esses dados serão perdidos.
precisa saber é o seguinte

Sim, exceto os desvios UTC e GMT são inversos. Por exemplo, UTC-0700 é o mesmo que GMT + 0700. Realmente, tudo o que é digital deve estar usando o UTC atualmente.
Matt Johnson-Pint

1
@ Matt: você tem certeza de que as compensações UTC e GMT são inversas? onde posso ler sobre isso?
Reto Höhener,

Na verdade, acho que estava errado antes. GMT e UTC não são invertidos. É que existem implementações que as mostram inversamente, como o banco de dados IANA / Olson / TZDB. Veja aqui . Outra área em que você vê deslocamentos inversos está na função getTimezoneOffset () do javascript.
Matt Johnson-Pint

@MattJohnson: Esses são hacks e devem ser abolidos.
Alix Axel

2

Aqui está a minha experiência: -

(Não requer nenhuma biblioteca de terceiros)

  • No lado do servidor, armazene horários no formato UTC para que todos os valores de data / hora no banco de dados estejam em um único padrão, independentemente da localização de usuários, servidores, fusos horários ou horário de verão.
  • Na camada da interface do usuário ou nos e-mails enviados ao usuário, você precisa mostrar os horários de acordo com o usuário. Nesse caso, você precisa ter o deslocamento do fuso horário do usuário para poder adicionar esse deslocamento ao valor UTC do banco de dados, o que resultará no horário local do usuário. Você pode reduzir o fuso horário do usuário ao se inscrever ou pode detectá-lo automaticamente nas plataformas da Web e dispositivos móveis. Para sites, o método getTimezoneOffset () da função JavaScript é um padrão desde a versão 1.0 e compatível com todos os navegadores. (Ref: http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp )

Isso não funciona quando você considera as alterações no horário de verão. getTimezoneOffsetretorna o deslocamento da data e hora em que você o chama. Esse deslocamento pode mudar quando um fuso horário passa ou sai do horário de verão. Veja "fuso horário! = Deslocamento" no wiki da tag de fuso horário .
Matt Johnson-Pint

1
Se você deseja armazenar um alarme como "faça algo às 10:00", não poderá armazená-lo no UTC, devido às mudanças no horário de verão. Você deve armazená-lo em relação à hora local.
23417 Alex

2

O vídeo de Tom Scott sobre os fusos horários no YouTube no canal Computerphile também tem uma descrição agradável e divertida do tópico. Exemplos incluem:

  • Samoa (uma ilha no Oceano Pacífico) alterando seu fuso horário em 24 horas para facilitar o comércio com a Austrália e a Nova Zelândia,
  • Cisjordânia , onde 2 populações de pessoas seguem diferentes fusos horários,
  • O século 18 muda do calendário juliano para o calendário gregoriano (que aconteceu no século 20 na Rússia).

1

Na verdade, o kernel32.dll não exporta SystemTimeToTzSpecificLocation. No entanto, exporta os dois seguintes: SystemTimeToTzSpecificLocalTime e TzSpecificLocalTimeToSystemTime ...


1

Nunca confie apenas em construtores como

 new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)

Eles podem lançar exceções quando um determinado horário não existir devido ao horário de verão. Em vez disso, crie seus próprios métodos para criar essas datas. Neles, identifique as exceções que ocorrem devido ao horário de verão e ajuste o tempo necessário com o deslocamento da transição. O horário de verão pode ocorrer em datas diferentes e em horários diferentes (mesmo à meia-noite no Brasil) de acordo com o fuso horário.


1

Apenas um exemplo para provar que o tempo de manuseio é a grande bagunça descrita e que você nunca pode ser complacente. Em vários pontos desta página, os segundos bissextos foram ignorados.

Vários anos atrás, o sistema operacional Android usava satélites GPS para obter uma referência de horário UTC, mas ignorava o fato de que os satélites GPS não usam segundos bissextos. Ninguém percebeu até haver confusão na véspera de Ano Novo, quando os usuários de telefones da Apple e Android fizeram suas contagens regressivas com cerca de 15 segundos de diferença.

Acho que já foi corrigido, mas você nunca sabe quando esses 'pequenos detalhes' voltarão para assombrá-lo.


1
  • Nunca, nunca armazene a hora local sem seu deslocamento UTC (ou uma referência ao fuso horário) - exemplos de como não fazer isso incluem FAT32 e struct tmem C.¹
  • Entenda que um fuso horário é uma combinação de
    • um conjunto de compensações UTC (por exemplo, +0100 no inverno, +0200 no verão)
    • regras para quando a transição ocorre (que pode mudar ao longo do tempo: por exemplo, nos anos 90, a UE harmonizou a transição como sendo nos últimos domingos de março e outubro, às 02:00 hora padrão / 03:00 DST; anteriormente isso diferia entre os Estados membros).

Implement Algumas implementações de struct tmarmazenam o deslocamento UTC, mas isso não foi incluído no padrão.


-4

Ao lidar com bancos de dados (em particular o MySQL , mas isso se aplica à maioria dos bancos de dados), achei difícil armazenar o UTC.

  • Os bancos de dados geralmente trabalham com data e hora do servidor por padrão (ou seja, CURRENT_TIMESTAMP).
  • Talvez você não consiga alterar o fuso horário do servidor.
  • Mesmo se você conseguir alterar o fuso horário, poderá ter um código de terceiros que espera que o fuso horário do servidor seja local.

Achei mais fácil armazenar o datetime do servidor no banco de dados e permitir que o banco de dados convertesse o datetime de volta em UTC (ou seja, UNIX_TIMESTAMP ()) nas instruções SQL. Depois disso, você pode usar a data e hora como UTC no seu código.

Se você tem 100% de controle sobre o servidor e todo o código, provavelmente é melhor alterar o fuso horário do servidor para UTC.


A hora local (a hora do servidor) pode ser ambígua durante as transições de horário de verão no estilo "fallback". Não é confiável para usar como você descreveu. Pode haver mais de uma hora UTC que a hora local do servidor pode estar representando.
precisa saber é o seguinte

A hora local é perfeitamente adequada se o servidor estiver localizado em um fuso horário correto, ou seja, um que não faça o horário de verão.
sayap
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.