(Nota: aunque relacionado, este desafío no es un duplicado de este porque requiere determinar los segundos bisiestos automáticamente en lugar de codificar sus tiempos, y no es un duplicado de este porque la mayor parte de la dificultad proviene de determinar el tiempo sin sesgar el segundo salto , algo que la mayoría de las veces las API no hacen de manera predeterminada. Como tal, es probable que una solución se vea diferente de una solución a cualquiera de esos desafíos)
Estamos llegando a finales de 2016, pero llevará un poco más de lo que la mayoría de la gente espera. Así que aquí hay un desafío para celebrar nuestro segundo extra este año.
Salida de la hora actual en UTC, como horas, minutos, segundos. (Por ejemplo, los formatos de salida legítimos para el mediodía incluirían 12:00:00
y [12,0,0]
; el formato no es muy importante aquí).
Sin embargo, hay un giro: su programa debe manejar los segundos intercalares adecuadamente, tanto en el pasado como en el futuro. Esto significa que su programa tendrá que obtener una lista de segundos intercalares de alguna fuente en línea o actualizada / actualizable automáticamente. Puede conectarse a Internet para obtener esto si lo desea. Sin embargo, solo puede conectarse a una URL que sea anterior a este desafío (es decir, no descargar partes de su programa desde otro lugar), y no puede usar la conexión para determinar la hora actual (específicamente: su programa debe funcionar incluso si intenta acceder Internet devuelve una página que está inactiva hasta 24 horas).
La mayoría de las API predeterminadas de los sistemas operativos para la hora actual sesgarán el tiempo en segundos bisiestos para ocultarlas de los programas que de otro modo podrían confundirse. Como tal, la principal dificultad de este desafío es encontrar un método o una API para deshacer eso, y calcular la hora actual no modificada en UTC.
En teoría, su programa debe ser perfectamente preciso si se ejecuta en una computadora infinitamente rápida, y no debe tomar más de cero intencionalmente en ejecutarse. (Por supuesto, en la práctica, su programa se ejecutará en una computadora imperfecta, por lo que probablemente no se ejecutará instantáneamente. No tiene que preocuparse de que esto invalide los resultados, pero no debe depender de él para la corrección de su programa. )
Su programa debe funcionar independientemente de la zona horaria en la que esté configurado el reloj del sistema. (Sin embargo, puede solicitar información del sistema operativo o del entorno sobre qué zona horaria se está utilizando y puede suponer que la respuesta es precisa).
Como código de golf , gana el programa más corto. ¡Buena suerte!
Respuestas:
PowerShell , 161 bytes
Pruébalo en línea! (no funciona aquí, parece que TIO no reconoce
irm
yiwr
, ¿tal vez es una característica de seguridad?)Prueba lógica (fecha codificada):
Notas
Hay un salto de línea literal TABy uno literal (
0xA
) en la cadena de expresiones regulares, por lo que no tuve que escapar de ellos (guardado 1 byte cada uno).Explicación
Los tiempos dados (de los segundos bisiestos) en el archivo ietf están en segundos desde la época NTP que es
1/1/1900 00:00:00
. En Windows, un "tic" es simplemente una décima millonésima de segundo (10,000,000 ticks / seg).Si agrega un número entero a un
[datetime]
, cuenta el valor entero como ticks, por lo que estoy usando el valor de tick codificado de NTP epoch, luego lo resta del valor de tick del tiempo UTC actual (cuyo valor original se asigna simultáneamente a$d
)Para hacer que el valor de la marca codificada sea más pequeño, eliminé algunos ceros (9 de ellos) y los dividí entre 98, luego los multipliqué por
98e9
(98 * 10 9 ).El resultado de esa resta es el valor en ticks desde la época NTP. Eso se divide por
1e8
(no1e9
, por razones que serán claras en un momento) para obtener el valor en segundos (más o menos) desde la época de NTP. Será más pequeño por un factor de 10, en realidad.Al recuperar el documento del IETF, en lugar de dividirlo en líneas primero, luego procesar las líneas con las marcas de tiempo, decidí dividir en saltos de línea y en TABcaracteres, ya que eso es lo que viene después de la marca de tiempo. Debido a una sola línea errante en el archivo, eso solo incluiría una marca de tiempo adicional que no queremos. La línea se ve así:
Así que cambié la expresión regular para dividir
[^@]\t
(cualquier carácter que no sea@
seguido por a TAB) que funciona para excluir esa línea, pero también termina consumiendo el último0
en cada una de las marcas de tiempo.Es por eso que divido por
1e8
y no1e9
, para dar cuenta de los desaparecidos0
.La marca de tiempo actual se verifica para ver si existe dentro de la lista de marcas de segundo de salto neutralizadas. Todo este proceso que describí está dentro del descriptor de acceso a la matriz
[]
, por lo que el[bool]
valor resultante se fusiona a a0
($false
) o1
($true
). La matriz en la que estamos indexando contiene dos elementos: una cadena de formato para mostrar la hora y una codificada23:59:60
. La veracidad de la comparación mencionada anteriormente determina cuál se elegirá, y eso se alimenta al operador de formato-f
con la fecha actual previamente asignada$d
como parámetro.fuente