(Uwaga: pomimo tego, że jest to powiązane, to wyzwanie nie jest duplikatem tego, ponieważ wymaga automatycznego określenia sekund przestępnych, a nie zakodowania ich czasów i nie jest duplikatem tego, ponieważ większość trudności wynika z określenia czasu bez drugiego skoku , coś, czego większość interfejsów API nie robi domyślnie. W związku z tym rozwiązanie może wyglądać inaczej niż rozwiązanie któregoś z tych wyzwań).
Zbliżamy się do końca 2016 roku, ale potrwa to nieco dłużej, niż większość ludzi się spodziewa. Oto wyzwanie świętowania naszej dodatkowej sekundy w tym roku.
Podaj aktualny czas w UTC, jako godziny, minuty, sekundy. (Na przykład prawidłowe formaty wyjściowe na południe powinny zawierać 12:00:00
i [12,0,0]
; formatowanie nie jest tutaj niezwykle ważne).
Jest jednak pewien zwrot: twój program musi odpowiednio obsługiwać sekundy przestępne , zarówno z przeszłości, jak i przyszłości. Oznacza to, że Twój program będzie musiał uzyskać listę sekund przestępnych z niektórych źródeł online lub automatycznie aktualizowanych / aktualizowanych. Jeśli chcesz, możesz połączyć się z Internetem. Możesz jednak połączyć się tylko z adresem URL, który wyprzedza to wyzwanie (tj. Nie pobierać części programu z innego miejsca) i nie możesz używać połączenia do określenia aktualnego czasu (w szczególności: Twój program musi działać, nawet jeśli jakakolwiek próba dostępu Internet zwraca stronę, która jest do 24 godzin nieaktualna).
Domyślne interfejsy API większości systemów operacyjnych na bieżący czas będą przechylać czas około sekund przestępnych, aby ukryć je przed programami, które w innym przypadku mogłyby zostać pomylone. W związku z tym główną trudnością tego wyzwania jest znalezienie metody lub interfejsu API w celu cofnięcia tego i obliczenia prawdziwego niezmodyfikowanego bieżącego czasu w UTC.
Teoretycznie twój program powinien być idealnie dokładny, jeśli działał na nieskończenie szybkim komputerze i nie mógł celowo działać dłużej niż zero czasu. (Oczywiście w praktyce Twój program będzie działał na niedoskonałym komputerze, a więc prawdopodobnie nie uruchomi się natychmiast. Nie musisz się martwić o unieważnienie wyników, ale nie możesz polegać na nim pod względem poprawności programu. )
Twój program musi działać niezależnie od strefy czasowej, na którą ustawiony jest zegar systemowy. (Może jednak zażądać od systemu operacyjnego lub środowiska informacji o używanej strefie czasowej i może założyć, że odpowiedź jest poprawna).
Jak golf-golfwygrywa najkrótszy program. Powodzenia!
Odpowiedzi:
PowerShell , 161 bajtów
Wypróbuj online! (tutaj nie działa, wygląda na to, że TIO nie rozpoznaje
irm
iiwr
może to funkcja bezpieczeństwa?)Test logiczny (data zakodowania):
Notatki
W łańcuchu wyrażeń regularnych występuje literał TABi dosłowny podział wiersza (
0xA
), więc nie musiałem przed nimi uciekać (zapisałem 1 bajt każdy).Wyjaśnienie
Czasy podane (w sekundach przestępnych) w pliku ietf są w sekundach od epoki NTP, która jest
1/1/1900 00:00:00
. W systemie Windows „tyknięcie” to po prostu jedna dziesiąta milionowej sekundy (10 000 000 tyknięć / s).Jeśli dodasz liczbę całkowitą do
[datetime]
, liczona jest wartość całkowita jako tiki, więc używam zakodowanej wartości tonu z epoki NTP, a następnie odejmuję ją od wartości tiku bieżącego czasu UTC (której pierwotna wartość jest jednocześnie przypisywana do$d
).Aby zmniejszyć wartość zaznaczenia na sztywno, zabrałem kilka zer (9 z nich) i podzieliłem przez 98, a następnie pomnożyłem przez
98e9
(98 * 10 9 ).Wynikiem tego odejmowania jest wartość w tikach od epoki NTP. Dzieli się to
1e8
(nie1e9
, z powodów, które za chwilę będą jasne), aby uzyskać wartość w sekundach (w pewnym sensie) od epoki NTP. W rzeczywistości będzie mniejszy 10 razy.Odzyskując dokument z IETF, zamiast najpierw podzielić go na linie, a następnie przetworzyć linie ze znacznikami czasu, postanowiłem podzielić zarówno na podziały linii, jak i na TABznaki, ponieważ to jest po znaczniku czasu. Z powodu pojedynczej błędnej linii w pliku, sam ten zawierałby dodatkowy znacznik czasu, którego nie chcemy. Linia wygląda następująco:
Zmieniłem więc wyrażenie regularne na split
[^@]\t
(dowolny znak, po którym nie@
następuje a TAB), co działa w celu wykluczenia tej linii, ale w końcu pochłania ostatnie0
w każdym ze znaczników czasu.Dlatego dzielę według,
1e8
a nie1e9
, aby uwzględnić brakujące0
.Bieżący znacznik czasu jest sprawdzany, aby zobaczyć, czy istnieje on na liście znaczników czasowych drugiego wyskoku. Cały ten proces, który opisałem, znajduje się wewnątrz akcesorium tablicowego
[]
, więc wynikowa[bool]
wartość jest łączona w0
($false
) lub1
($true
). Tablica, w której indeksujemy, zawiera dwa elementy: ciąg formatu do wyświetlania czasu i zakodowany na stałe23:59:60
. Prawdziwość wspomnianego porównania określa, które zostanie wybrane, i które jest podawane do operatora formatu-f
z wcześniej przypisaną bieżącą datą$d
jako parametrem.źródło