Czy istnieje sposób na wyodrębnienie momentu historycznych sekund przestępnych z bazy danych strefy czasowej, która jest dystrybuowana w większości dystrybucji Linuksa? Szukam rozwiązania w Pythonie, ale wszystko, co działa na linii poleceń byłoby również w porządku.Wyodrębnij historyczne sekundy przestępne z tzdata
Moim przypadkiem użycia jest konwersja pomiędzy czasem GPS (czyli w zasadzie liczbą sekund od pierwszego włączenia GPS-a w 1980 r.) A czasem UTC lub czasem lokalnym. Czas UTC jest korygowany co sekundę, a czas GPS rośnie liniowo. Jest to równoznaczne z konwersją między UTC i TAI. TAI również ignoruje sekundy przestępne, więc czasy TAI i GPS powinny zawsze ewoluować z takim samym przesunięciem. W pracy wykorzystujemy czas GPS jako standard czasowy do synchronizowania obserwacji astronomicznych na całym świecie.
mam funkcje, które przekształcają pomiędzy GPS a UTC czasu pracy, ale musiałem twardym kodu tabelę sekundy przestępne, które dostaję here (plik tzdata2013xx.tar.gz
zawiera plik o nazwie leapseconds
). Muszę aktualizować ten plik ręcznie co kilka lat, kiedy ogłoszony zostanie nowy leapsecond. Wolałbym uzyskać te informacje ze standardowego tzdata, który jest automatycznie aktualizowany przez aktualizacje systemu kilka razy w roku.
Jestem prawie pewien, że informacje są ukryte w niektórych plikach binarnych gdzieś w /usr/share/zoneinfo/
. Byłem w stanie wydobyć niektóre z nich za pomocą struct.unpack
(man tzfile
daje pewne informacje na temat formatu), ale nigdy nie dostałem go działa całkowicie. Czy są jakieś standardowe pakiety, które mogą uzyskać dostęp do tych informacji? Wiem o pytz, który wydaje się uzyskać standardowe informacje DST z tej samej bazy danych, ale nie daje dostępu do sekund przestępnych. Znalazłem także tai64n, ale patrząc na jego kod źródłowy, zawiera on po prostu zakodowaną tabelę.
EDIT
Zainspirowany odpowiedź steveha i pewnego kodu w pytz/tzfile.py, ja wreszcie roztwór roboczy (testowane na py2.5 i py2.7):
from struct import unpack, calcsize
from datetime import datetime
def print_leap(tzfile = '/usr/share/zoneinfo/right/UTC'):
with open(tzfile, 'rb') as f:
# read header
fmt = '>4s c 15x 6l'
(magic, format, ttisgmtcnt, ttisstdcnt,leapcnt, timecnt,
typecnt, charcnt) = unpack(fmt, f.read(calcsize(fmt)))
assert magic == 'TZif'.encode('US-ASCII'), 'Not a timezone file'
print 'Found %i leapseconds:' % leapcnt
# skip over some uninteresting data
fmt = '>%(timecnt)dl %(timecnt)dB %(ttinfo)s %(charcnt)ds' % dict(
timecnt=timecnt, ttinfo='lBB'*typecnt, charcnt=charcnt)
f.read(calcsize(fmt))
#read leap-seconds
fmt = '>2l'
for i in xrange(leapcnt):
tleap, nleap = unpack(fmt, f.read(calcsize(fmt)))
print datetime.utcfromtimestamp(tleap-nleap+1)
z wynikiem
In [2]: print_leap()
Found 25 leapseconds:
1972-07-01 00:00:00
1973-01-01 00:00:00
1974-01-01 00:00:00
...
2006-01-01 00:00:00
2009-01-01 00:00:00
2012-07-01 00:00:00
Podczas gdy to rozwiąże moje pytanie, prawdopodobnie nie pójdę po to rozwiązanie. Zamiast tego dołączę do mojego kodu kod leap-seconds.list, jak sugeruje Matt Johnson. Wydaje się, że jest to autorytatywna lista używana jako źródło tzdata i prawdopodobnie jest aktualizowana przez NIST dwa razy w roku. Oznacza to, że będę musiał ręcznie przeprowadzić aktualizację, ale ten plik jest łatwy do przeanalizowania i zawiera datę wygaśnięcia (której prawdopodobnie brakuje w tzdacie).
wiem, są one również opublikowane [tutaj] (https://github.com/eggert/tz/blob/master/leap-seconds.list), i wiem też, że są one zestawiane z 'Zic ', więc powinny znajdować się w aktualizacjach tzdata. Jak zauważyłeś, plik [tzfile] (http://man7.org/linux/man-pages/man5/tzfile.5.html) pokazuje go w 'tzh_leapcnt', więc możesz go zdobyć w ten sposób. W tej chwili nie mam dla ciebie bardziej bezpośredniej odpowiedzi. Może ktoś inny to zrobi. –
tzdaty przechowuje przesunięcia z UTC. Dlaczego miałby zawierać leapseconds? – mattexx
@mattexx Nie pytaj mnie, dlaczego, ale pliki binarne tzdata zawierają informacje typu "leap-second", może właśnie w ten sposób, w jaki sposób konwersje czasowe mnie interesują. Ludzie utrzymujący to [baza danych] (http: // en .wikipedia.org/wiki/Olson_database) są bardzo skrupulatne, jeśli chodzi o zapisywanie historycznych zmian w definicjach czasu, czasami dostarczając aktualizacje 10 razy w roku, ponieważ jakiś szalony dyktator przesunął czas letni o jeden dzień. Śledzenie upływu czasu jest o wiele łatwiejsze, ponieważ IERS publikuje regularnie biuletyny i zwykle są one ogłaszane pół roku wcześniej. –