Роздрукуйте поточний час…, враховуючи високосні секунди


9

(Примітка. Хоча цей виклик не є дублікатом цього, оскільки він вимагає автоматичного визначення секундних стрибків, а не жорсткого кодування їх часу, і не є дублікатом цього, оскільки більша частина труднощів пов'язана з визначенням часу без стрибків другого перекосу. , те, що більшість API часу не роблять за замовчуванням. Як таке, рішення, ймовірно, виглядає відмінним від рішення для будь-якого з цих викликів.)

Ми підходимо до кінця 2016 року, але це займе трохи більше часу, ніж очікує більшість людей. Тож ось виклик святкувати нашу додаткову секунду цього року.

Виведіть поточний час у UTC, як години, хвилини, секунди. (Наприклад, законні вихідні формати для полудня включатимуть 12:00:00і [12,0,0]; форматування тут не має великого значення.)

Однак є поворот: ваша програма повинна обробляти високосні секунди належним чином, як минулі, так і майбутні. Це означає, що вашій програмі доведеться отримати список високосних секунд з якогось онлайн-джерела або автоматично оновленого / оновленого джерела. Ви можете підключитися до Інтернету, щоб отримати це, якщо бажаєте. Однак ви можете підключитися лише до URL-адреси, яка передує цьому виклику (тобто не завантажуйте частини програми з іншого місця), і ви не можете використовувати з'єднання для визначення поточного часу (зокрема: ваша програма повинна функціонувати навіть у разі будь-якої спроби доступу Інтернет повертає сторінку, яка до 24 годин застаріла).

Більшість API за замовчуванням для поточного часу API для операційних систем перекосують час у високосні секунди, щоб сховати їх від програм, які в іншому випадку можуть бути заплутані. Отже, головна складність цього завдання полягає у пошуку методу чи API, щоб скасувати це та відпрацювати справжній незмінений поточний час у UTC.

Теоретично ваша програма повинна бути абсолютно точною, якщо вона працювала на нескінченно швидкому комп’ютері і не повинна навмисно забирати більше ніж нульовий час для запуску. (Звичайно, на практиці ваша програма буде працювати на недосконалому комп'ютері, і тому, ймовірно, не запуститься миттєво. Вам не доведеться турбуватися про те, що результати буде визнано недійсним, але це не повинно залежати від правильності вашої програми. )

Ваша програма повинна функціонувати незалежно від того, для якого часового поясу встановлено системний годинник. (Однак він може вимагати отримання інформації від операційної системи або оточення щодо того, який часовий пояс використовується, і може вважати, що відповідь точна.)

Як , виграє найкоротша програма. Удачі!


Відповіді:


2

PowerShell , 161 байт

(('{0:H:m:s}','23:59:60')[(($d=[datetime]::UtcNow).Ticks-6114960*98e9)/1e8-in((irm ietf.org/timezones/data/leap-seconds.list)-split'[^@]	|
'-match'^\d{9}')])-f$d

Спробуйте в Інтернеті! (тут не працює, здається, TIO не розпізнає irmі iwr, можливо, це функція безпеки?)

Логічний тест (кодована дата):

(('{0:H:m:s}','23:59:60')[(($d=[datetime]'1/1/2017 00:00:00').Ticks-6114960*98e9)/1e8-in((irm ietf.org/timezones/data/leap-seconds.list)-split'[^@]	|
'-match'^\d{9}')])-f$d

Примітки

У рядку регулярних виразів є буквальний TABта буквальний 0xAрядковий рядок ( ), так що мені не довелося уникати їх (збережено по 1 байті кожен).

Пояснення

Часи, подані (з високосних секунд) у файлі ietf, є секундами з моменту епохи NTP 1/1/1900 00:00:00. У Windows "галочка" - це просто одна десятимільйонна частина секунди (10 000 000 тиків / сек).

Якщо ви додасте ціле число до числа, [datetime]воно зараховує ціле число як тики, тож я використовую твердокодированное значення галочки NTP epoch, а потім віднімаю його від тикового значення поточного часу UTC (початкове значення якого одночасно призначається до $d).

Щоб зменшити значення жорсткого коду, я забрав кілька нулів (9 з них) і розділив на 98, а потім помножив на 98e9(98 * 10 9 ).

Результатом цього віднімання є значення в тиках, починаючи з епохи NTP. Це ділиться на 1e8(не 1e9з причин, які будуть зрозумілі через мить), щоб отримати значення в секундах (подібних) з епохи NTP. Він буде меншим на 10 разів.

Отримавши документ з IETF, замість того, щоб спочатку розділити його на рядки, потім обробити рядки часовими позначками, я вирішив розділити як на розриви рядків, так і на TABсимволи, оскільки саме це настає після позначки часу. Через єдину помилкову рядок у файлі, це одне лише міститиме додаткову мітку часу, яку ми не хочемо. Рядок виглядає приблизно так:

#@	3707596800

Тому я змінив регулярний вираз на поділ [^@]\t(будь-який символ, за яким не @слідує а TAB), який працює на виключення цього рядка, але також закінчує споживання останнього 0у кожній із часових позначок.

Тому я ділю на, 1e8а не 1e9, щоб рахувати зниклих 0.

Поточна мітка часу перевіряється, щоб вона існувала всередині списку нейтралізованих стрибкових секундних міток. Весь цей процес, який я описав, знаходиться всередині аксесуара масиву [], тому отримане [bool]значення зливається з 0( $false) або 1( $true). Масив, в який ми індексуємо, містить два елементи: форматну рядок для відображення часу та жорсткий код 23:59:60. Правдивість вищезгаданого порівняння визначає, який з них буде обраний, і який подається в оператор формату -fз попередньо призначеною поточною датою $dяк його параметр.


Що це друкує друге після високосної секунди? Я можу дотримуватися логіки протягом стрибків секунд, але не впевнений, що можу слідувати логіці раз у обидві сторони. (Відображає, що Windows, як 00:00:00, так і стрибкову секунду, і наступну секунду?)

@ ais523 він відображатиме другу після стрибкової секунди як би не був системний час. Windows не знає про високосні секунди, тому годинник буде швидкий за 1 секунду, поки не буде виправлено налаштування синхронізації або вручну. Зважаючи на вимоги, я не можу реально підлаштовуватися під це, оскільки неможливо визначити, правильний чи системний час без використання зовнішнього джерела часу, яке заборонено. З найкращого, що я міг зробити, - це додати код до цього, що змушує синхронізувати NTP після того, як він надрукував час, що, звичайно, може вийти з ладу (помилка мережі, відсутність встановленого джерела часу тощо), якщо це навіть дозволено.
британіст
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.