有沒有辦法從大多數linux發行版上分佈的時區數據庫中提取歷史性閏秒?我正在尋找python的解決方案,但在命令行上工作的任何東西都可以。從tzdata中提取歷史性閏秒
我的用例是在GPS時間(基本上是自1980年第一顆GPS衛星開啓以來的秒數)和UTC或本地時間之間進行轉換。 UTC不時調整閏秒,而GPS時間線性增加。這相當於在UTC和TAI之間轉換。 TAI也忽略了閏秒,因此TAI和GPS時間總是應該以相同的偏移量進行演變。在工作中,我們使用全球定位系統時間作爲同步世界各地天文觀測的時間標準。
我有工作,全球定位系統,時間和UTC之間轉換的功能,但我不得不硬編碼的閏秒的表,我得到here(文件tzdata2013xx.tar.gz
包含名爲leapseconds
文件)。我必須每隔幾年手動更新一次這個文件,當一個新的突發事件宣佈時。我寧願從標準的tzdata中獲取這些信息,tzdata每年通過系統更新自動更新。
我很確定這些信息隱藏在/usr/share/zoneinfo/
某處的某些二進制文件中。我已經能夠使用struct.unpack
(man tzfile
提供有關格式的一些信息)提取一些信息,但我從來沒有完全實現它。有沒有可以訪問這些信息的標準軟件包?我知道pytz,它似乎從同一個數據庫獲得標準的DST信息,但它不能訪問閏秒。我也發現tai64n,但看着它的源代碼,它只包含一個硬編碼表。
編輯
通過steveha答案,並在pytz/tzfile.py一些代碼的啓發,我終於得到了一個有效的解決方案(上py2.5和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)
與結果
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
雖然這確實解決了我的問題,我可能不會去這個解決方案。相反,我將按照Matt Johnson的建議,將leap-seconds.list包含在我的代碼中。這似乎是用作tzdata來源的權威列表,並且可能每年兩次由NIST更新。這意味着我將不得不手動更新,但是這個文件很容易解析並且包含到期日期(這個tzdata似乎缺失)。
我知道他們也發表[這裏](https://github.com/eggert/tz/blob/master/leap-seconds.list),我也知道,他們正在與'ZIC編譯',所以他們應該在tzdata更新。正如你注意到的,[tzfile](http://man7.org/linux/man-pages/man5/tzfile.5.html)在'tzh_leapcnt'中顯示了它,所以你可能會這樣。目前我沒有更直接的答案。也許別人會。 –
tzdata存儲來自UTC的偏移量。爲什麼它會包含跳躍? – mattexx
@mattexx不要問我爲什麼,但tzdata的二進制文件確實包含閏秒信息,可能正是爲了進行我感興趣的那種時間轉換。維護此數據庫的人(http:// en .wikipedia.org/wiki/Olson_database)在記錄時間定義的歷史性變化時非常細緻,有時每年提供10次更新,因爲一些瘋狂的獨裁者將夏令時移動了一天。由於IERS定期發佈公告,因此保持跟蹤跳躍更容易,並且通常會提前半年公佈。 –