From f4160c363b7e1bc8ad47a6c00d02c0856a3be17b Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Fri, 14 Jun 2019 12:35:14 +0200 Subject: [PATCH] Fix russia timezone detection (#637) Fixes https://github.com/esphome/issues/issues/378#issuecomment-500219634 --- esphome/components/time/__init__.py | 31 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/esphome/components/time/__init__.py b/esphome/components/time/__init__.py index 8c85a3d62f..634de26f00 100644 --- a/esphome/components/time/__init__.py +++ b/esphome/components/time/__init__.py @@ -52,6 +52,15 @@ def _tz_dst_str(dt): _tz_timedelta(td)) +def _non_dst_tz(tz, dt): + tzname = tz.tzname(dt) + utcoffset = tz.utcoffset(dt) + _LOGGER.info("Detected timezone '%s' with UTC offset %s", + tzname, _tz_timedelta(utcoffset)) + tzbase = '{}{}'.format(tzname, _tz_timedelta(-1 * utcoffset)) + return tzbase + + def convert_tz(pytz_obj): tz = pytz_obj @@ -59,24 +68,14 @@ def convert_tz(pytz_obj): first_january = datetime.datetime(year=now.year, month=1, day=1) if not isinstance(tz, pytz.tzinfo.DstTzInfo): - tzname = tz.tzname(first_january) - utcoffset = tz.utcoffset(first_january) - _LOGGER.info("Detected timezone '%s' with UTC offset %s", - tzname, _tz_timedelta(utcoffset)) - tzbase = '{}{}'.format(tzname, _tz_timedelta(-1 * utcoffset)) - return tzbase + return _non_dst_tz(tz, first_january) # pylint: disable=protected-access transition_times = tz._utc_transition_times transition_info = tz._transition_info idx = max(0, bisect.bisect_right(transition_times, now)) if idx >= len(transition_times): - tzname = tz.tzname(now) - utcoffset = tz.utcoffset(now) - _LOGGER.info("Detected timezone '%s' with UTC offset %s", - tzname, _tz_timedelta(utcoffset)) - tzbase = '{}{}'.format(tzname, _tz_timedelta(-1 * utcoffset)) - return tzbase + return _non_dst_tz(tz, now) idx1, idx2 = idx, idx + 1 dstoffset1 = transition_info[idx1][1] @@ -84,6 +83,14 @@ def convert_tz(pytz_obj): # Normalize to 1 being DST on idx1, idx2 = idx + 1, idx + 2 + if idx2 >= len(transition_times): + return _non_dst_tz(tz, now) + + if transition_times[idx2].year > now.year + 1: + # Next transition is scheduled after this year + # Probably a scheduler timezone change. + return _non_dst_tz(tz, now) + utcoffset_on, _, tzname_on = transition_info[idx1] utcoffset_off, _, tzname_off = transition_info[idx2] dst_begins_utc = transition_times[idx1]