我只是做了一下
man 5 tzfile,计算了一个偏移量,该偏移量将找到the秒信息,然后读取the秒信息。
您可以取消注释“ DEBUG:”打印语句,以查看它在文件中找到的更多内容。
编辑:程序更新为现在正确。现在
/usr/share/zoneinfo/right/UTC,它使用该文件,并且现在找到要打印的leap秒。
原始程序并未跳过在手册页中记录的timezeone缩写字符,但有些隐藏(“
…,并且tt_abbrind充当时区缩写字符数组的索引,该数组遵循ttinfo结构中的文件。”)。
import datetimeimport structTZFILE_MAGIC = 'TZif'.enpre('US-ASCII')def leap_seconds(f): """ Return a list of tuples of this format: (timestamp, number_of_seconds) timestamp: a 32-bit timestamp, seconds since the UNIX epoch number_of_seconds: how many leap-seconds occur at timestamp """ fmt = ">4s c 15x 6l" size = struct.calcsize(fmt) (tzfile_magic, tzfile_format, ttisgmtcnt, ttisstdcnt, leapcnt, timecnt, typecnt, charcnt) = struct.unpack(fmt, f.read(size)) #print("DEBUG: tzfile_magic: {} tzfile_format: {} ttisgmtcnt: {} ttisstdcnt: {} leapcnt: {} timecnt: {} typecnt: {} charcnt: {}".format(tzfile_magic, tzfile_format, ttisgmtcnt, ttisstdcnt, leapcnt, timecnt, typecnt, charcnt)) # Make sure it is a tzfile(5) file assert tzfile_magic == TZFILE_MAGIC, ( "Not a tzfile; file magic was: '{}'".format(tzfile_magic)) # comments below show struct pres such as "l" for 32-bit long integer offset = (timecnt*4 # transition times, each "l" + timecnt*1 # indices tying transition time to ttinfo values, each "B" + typecnt*6 # ttinfo structs, each stored as "lBB" + charcnt*1) # timezone abbreviation chars, each "c" f.seek(offset, 1) # seek offset bytes from current position fmt = '>{}l'.format(leapcnt*2) #print("DEBUG: leapcnt: {} fmt: '{}'".format(leapcnt, fmt)) size = struct.calcsize(fmt) data = struct.unpack(fmt, f.read(size)) lst = [(data[i], data[i+1]) for i in range(0, len(data), 2)] assert all(lst[i][0] < lst[i+1][0] for i in range(len(lst)-1)) assert all(lst[i][1] == lst[i+1][1]-1 for i in range(len(lst)-1)) return lstdef print_leaps(leap_lst): # leap_lst is tuples: (timestamp, num_leap_seconds) for ts, num_secs in leap_lst: print(datetime.datetime.utcfromtimestamp(ts - num_secs+1))if __name__ == '__main__': import os zoneinfo_fname = '/usr/share/zoneinfo/right/UTC' with open(zoneinfo_fname, 'rb') as f: leap_lst = leap_seconds(f) print_leaps(leap_lst)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)