Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/pytz/tzfile.py: 10%

76 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1''' 

2$Id: tzfile.py,v 1.8 2004/06/03 00:15:24 zenzen Exp $ 

3''' 

4 

5from datetime import datetime 

6from struct import unpack, calcsize 

7 

8from pytz.tzinfo import StaticTzInfo, DstTzInfo, memorized_ttinfo 

9from pytz.tzinfo import memorized_datetime, memorized_timedelta 

10 

11 

12def _byte_string(s): 

13 """Cast a string or byte string to an ASCII byte string.""" 

14 return s.encode('ASCII') 

15 

16_NULL = _byte_string('\0') 

17 

18 

19def _std_string(s): 

20 """Cast a string or byte string to an ASCII string.""" 

21 return str(s.decode('ASCII')) 

22 

23 

24def build_tzinfo(zone, fp): 

25 head_fmt = '>4s c 15x 6l' 

26 head_size = calcsize(head_fmt) 

27 (magic, format, ttisgmtcnt, ttisstdcnt, leapcnt, timecnt, 

28 typecnt, charcnt) = unpack(head_fmt, fp.read(head_size)) 

29 

30 # Make sure it is a tzfile(5) file 

31 assert magic == _byte_string('TZif'), 'Got magic %s' % repr(magic) 

32 

33 # Read out the transition times, localtime indices and ttinfo structures. 

34 data_fmt = '>%(timecnt)dl %(timecnt)dB %(ttinfo)s %(charcnt)ds' % dict( 

35 timecnt=timecnt, ttinfo='lBB' * typecnt, charcnt=charcnt) 

36 data_size = calcsize(data_fmt) 

37 data = unpack(data_fmt, fp.read(data_size)) 

38 

39 # make sure we unpacked the right number of values 

40 assert len(data) == 2 * timecnt + 3 * typecnt + 1 

41 transitions = [memorized_datetime(trans) 

42 for trans in data[:timecnt]] 

43 lindexes = list(data[timecnt:2 * timecnt]) 

44 ttinfo_raw = data[2 * timecnt:-1] 

45 tznames_raw = data[-1] 

46 del data 

47 

48 # Process ttinfo into separate structs 

49 ttinfo = [] 

50 tznames = {} 

51 i = 0 

52 while i < len(ttinfo_raw): 

53 # have we looked up this timezone name yet? 

54 tzname_offset = ttinfo_raw[i + 2] 

55 if tzname_offset not in tznames: 

56 nul = tznames_raw.find(_NULL, tzname_offset) 

57 if nul < 0: 

58 nul = len(tznames_raw) 

59 tznames[tzname_offset] = _std_string( 

60 tznames_raw[tzname_offset:nul]) 

61 ttinfo.append((ttinfo_raw[i], 

62 bool(ttinfo_raw[i + 1]), 

63 tznames[tzname_offset])) 

64 i += 3 

65 

66 # Now build the timezone object 

67 if len(ttinfo) == 1 or len(transitions) == 0: 

68 ttinfo[0][0], ttinfo[0][2] 

69 cls = type(zone, (StaticTzInfo,), dict( 

70 zone=zone, 

71 _utcoffset=memorized_timedelta(ttinfo[0][0]), 

72 _tzname=ttinfo[0][2])) 

73 else: 

74 # Early dates use the first standard time ttinfo 

75 i = 0 

76 while ttinfo[i][1]: 

77 i += 1 

78 if ttinfo[i] == ttinfo[lindexes[0]]: 

79 transitions[0] = datetime.min 

80 else: 

81 transitions.insert(0, datetime.min) 

82 lindexes.insert(0, i) 

83 

84 # calculate transition info 

85 transition_info = [] 

86 for i in range(len(transitions)): 

87 inf = ttinfo[lindexes[i]] 

88 utcoffset = inf[0] 

89 if not inf[1]: 

90 dst = 0 

91 else: 

92 for j in range(i - 1, -1, -1): 

93 prev_inf = ttinfo[lindexes[j]] 

94 if not prev_inf[1]: 

95 break 

96 dst = inf[0] - prev_inf[0] # dst offset 

97 

98 # Bad dst? Look further. DST > 24 hours happens when 

99 # a timzone has moved across the international dateline. 

100 if dst <= 0 or dst > 3600 * 3: 

101 for j in range(i + 1, len(transitions)): 

102 stdinf = ttinfo[lindexes[j]] 

103 if not stdinf[1]: 

104 dst = inf[0] - stdinf[0] 

105 if dst > 0: 

106 break # Found a useful std time. 

107 

108 tzname = inf[2] 

109 

110 # Round utcoffset and dst to the nearest minute or the 

111 # datetime library will complain. Conversions to these timezones 

112 # might be up to plus or minus 30 seconds out, but it is 

113 # the best we can do. 

114 utcoffset = int((utcoffset + 30) // 60) * 60 

115 dst = int((dst + 30) // 60) * 60 

116 transition_info.append(memorized_ttinfo(utcoffset, dst, tzname)) 

117 

118 cls = type(zone, (DstTzInfo,), dict( 

119 zone=zone, 

120 _utc_transition_times=transitions, 

121 _transition_info=transition_info)) 

122 

123 return cls() 

124 

125if __name__ == '__main__': 125 ↛ 126line 125 didn't jump to line 126, because the condition on line 125 was never true

126 import os.path 

127 from pprint import pprint 

128 base = os.path.join(os.path.dirname(__file__), 'zoneinfo') 

129 tz = build_tzinfo('Australia/Melbourne', 

130 open(os.path.join(base, 'Australia', 'Melbourne'), 'rb')) 

131 tz = build_tzinfo('US/Eastern', 

132 open(os.path.join(base, 'US', 'Eastern'), 'rb')) 

133 pprint(tz._utc_transition_times)