Fix improper usage of time.tzset() (#347)
* Fix improper usage of time.tzset()
time.tzname is a tuple containing the non-daylight-savings and
daylight-savings timezone abbreviations. However, when the TZ
environment variable is set to just the daylight-savings timezone (as
the clock module was changed to do in e31c58f
), time.tzset() will break
time.tzname by setting both elements of the tuple to that timezone,
causing the effective timezone to fallback to UTC:
>>> time.tzname
('CST', 'CDT')
>>> time.localtime().tm_hour
1
>>> os.environ.putenv('TZ', 'CST')
>>> time.tzset()
>>> time.tzname
('CST', 'CST')
>>> # ^^^ This is broken
...
>>> time.localtime().tm_hour
6
>>> os.environ.putenv('TZ', 'CST+06:00CDT')
>>> time.tzset()
>>> time.tzname
('CST', 'CDT')
>>> time.localtime().tm_hour
1
This fixes this incorrect behavior by building a proper TZ environment
variable to set localtime.
* Use time.timezone instead of time.altzone
* Make _get_local_tz a static method
This commit is contained in:
parent
c0cdfae1f8
commit
7cb2dcc255
@ -84,8 +84,25 @@ class Clock(IntervalModule):
|
|||||||
elif isinstance(self.format, str) or isinstance(self.format, tuple):
|
elif isinstance(self.format, str) or isinstance(self.format, tuple):
|
||||||
self.format = [self.format]
|
self.format = [self.format]
|
||||||
|
|
||||||
|
self._local_tzname = self._get_local_tz()
|
||||||
|
self._non_daylight_zone = time.tzname[0]
|
||||||
self.format = self.expand_formats(self.format)
|
self.format = self.expand_formats(self.format)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_local_tz():
|
||||||
|
'''
|
||||||
|
Returns a string representing localtime, suitable for setting localtime
|
||||||
|
using time.tzset().
|
||||||
|
|
||||||
|
https://docs.python.org/3/library/time.html#time.tzset
|
||||||
|
'''
|
||||||
|
hours_offset = time.timezone / 3600.0
|
||||||
|
plus_minus = '+' if hours_offset >= 0 else '-'
|
||||||
|
hh = int(hours_offset)
|
||||||
|
mm = 60 * (hours_offset % 1)
|
||||||
|
return '%s%s%02d:%02d%s' % (time.tzname[0], plus_minus,
|
||||||
|
hh, mm, time.tzname[1])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def expand_formats(formats):
|
def expand_formats(formats):
|
||||||
def expand_format(format_):
|
def expand_format(format_):
|
||||||
@ -94,15 +111,18 @@ class Clock(IntervalModule):
|
|||||||
if len(format_) > 1 and os.path.isfile('/usr/share/zoneinfo/' + format_[1]):
|
if len(format_) > 1 and os.path.isfile('/usr/share/zoneinfo/' + format_[1]):
|
||||||
return (format_[0], format_[1])
|
return (format_[0], format_[1])
|
||||||
else:
|
else:
|
||||||
return (format_[0], time.tzname[0])
|
return (format_[0], None)
|
||||||
return (format_, time.tzname[0])
|
return (format_, None)
|
||||||
|
|
||||||
return [expand_format(format_) for format_ in formats]
|
return [expand_format(format_) for format_ in formats]
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
# set timezone
|
# set timezone
|
||||||
if time.tzname[0] is not self.format[self.current_format_id][1]:
|
target_tz = self.format[self.current_format_id][1]
|
||||||
os.environ.putenv('TZ', self.format[self.current_format_id][1])
|
if target_tz is None and time.tzname[0] != self._non_daylight_zone \
|
||||||
|
or target_tz is not None and time.tzname[0] != target_tz:
|
||||||
|
new_tz = self._local_tzname if target_tz is None else target_tz
|
||||||
|
os.environ.putenv('TZ', new_tz)
|
||||||
time.tzset()
|
time.tzset()
|
||||||
|
|
||||||
self.output = {
|
self.output = {
|
||||||
|
Loading…
Reference in New Issue
Block a user