(Nota: embora relacionado, esse desafio não é uma duplicata deste, porque requer determinar segundos bissextos automaticamente, em vez de codificar seus tempos, e não é uma duplicata deste, porque a maior parte da dificuldade vem da determinação do tempo sem distorção do segundo bissexto. , algo que as APIs na maioria das vezes não fazem por padrão. Sendo assim, é provável que uma solução pareça diferente de uma solução para qualquer um desses desafios.)
Estamos chegando ao final de 2016, mas vai demorar um pouco mais do que a maioria das pessoas espera. Então, aqui está um desafio celebrando nosso segundo extra este ano.
Transmita a hora atual no UTC, como horas, minutos, segundos. (Por exemplo, os formatos de saída legítimos para o meio-dia incluiriam 12:00:00
e [12,0,0]
; a formatação não é muito importante aqui.)
No entanto, há uma reviravolta: seu programa deve lidar com segundos bissextos de maneira apropriada, tanto no passado quanto no futuro. Isso significa que seu programa precisará obter uma lista de segundos bissextos de alguma fonte online ou atualizada / atualizável automaticamente. Você pode se conectar à Internet para obter isso, se desejar. No entanto, você pode conectar-se apenas a um URL que antecede esse desafio (ou seja, sem baixar partes do seu programa de outro lugar) e não pode usar a conexão para determinar a hora atual (especificamente: o seu programa deve funcionar mesmo se houver alguma tentativa de acessar a Internet retorna uma página com até 24 horas de atraso).
As APIs padrão da maioria dos sistemas operacionais para o horário atual irão distorcer o tempo em segundos, para ocultá-los de programas que, de outra forma, poderiam ser confundidos. Como tal, a principal dificuldade desse desafio é encontrar um método ou uma API para desfazer isso e calcular o verdadeiro horário atual não modificado no UTC.
Em teoria, seu programa deve ser perfeitamente preciso se for executado em um computador infinitamente rápido e não deve intencionalmente levar mais que zero tempo para ser executado. (Obviamente, na prática, seu programa será executado em um computador imperfeito e, portanto, provavelmente não será executado instantaneamente. Você não precisa se preocupar com isso invalidando os resultados, mas não deve depender dele para a correção do seu programa. )
Seu programa deve funcionar independentemente do fuso horário em que o relógio do sistema está definido. (No entanto, ele pode solicitar informações do sistema operacional ou do ambiente sobre o fuso horário em uso e pode assumir que a resposta é precisa.)
Como um código de golfe , o programa mais curto vence. Boa sorte!
Respostas:
PowerShell , 161 bytes
Experimente online! (não funciona aqui, parece que o TIO não reconhece
irm
eiwr
, talvez seja um recurso de segurança?)Teste de lógica (data codificada):
Notas
Há um literal TABe um literal linebreak (
0xA
) na cadeia de caracteres regex, de modo que não precisei escapar deles (salvou 1 byte cada).Explicação
Os tempos indicados (dos segundos bissextos) no arquivo ietf estão em segundos desde a época NTP, que é
1/1/1900 00:00:00
. No Windows, um "tick" é simplesmente um milionésimo de segundo (10.000.000 ticks / s).Se você adicionar um número inteiro a um,
[datetime]
ele conta o valor inteiro como ticks, então estou usando o valor de tick codificado da época NTP, subtraindo-o do valor do tick da hora UTC atual (cujo valor original está sendo atribuído simultaneamente para$d
).Para diminuir o valor do tick codificado, tirei alguns zeros (9 deles) e dividi por 98, depois multipliquei por
98e9
(98 * 10 9 ).O resultado dessa subtração é o valor em ticks desde a época NTP. Isso é dividido por
1e8
(não1e9
, por razões que ficarão claras em um momento) para obter o valor em segundos (mais ou menos) desde a época do NTP. Será menor por um fator de 10, na verdade.Recuperando o documento da IETF, em vez de dividi-lo em linhas primeiro, depois processá-las com os carimbos de data / hora, decidi dividir nas quebras de linha e nos TABcaracteres, pois é o que vem depois do carimbo de data / hora. Devido a uma única linha incorreta no arquivo, isso por si só incluiria um carimbo de data / hora adicional que não queremos. A linha é assim:
Então, mudei a regex para dividir
[^@]\t
(qualquer caractere que não seja@
seguido de a TAB) que funciona para excluir essa linha, mas também acaba consumindo o último0
em cada um dos carimbos de data / hora.É por isso que divido por
1e8
e não1e9
, para dar conta dos desaparecidos0
.O registro de data e hora atual é verificado para ver se existe dentro da lista de registros de data e hora de segundo neutralizados. Todo esse processo que descrevi está dentro do acessador da matriz
[]
, portanto, o[bool]
valor resultante se junta a um0
($false
) ou1
($true
). A matriz na qual estamos indexando contém dois elementos: uma string de formato para exibir a hora e uma codificada23:59:60
. A veracidade da comparação mencionada determina qual será escolhida e que será inserida no operador de formato-f
com a data atual atribuída anteriormente$d
como parâmetro.fonte