get_system_offset for Europe/Dublin is wrong
ilcavero opened this issue · comments
The code assumes that daylight savings implies that time.altzone is in use, but in the case of Ireland it is the other way around. https://mm.icann.org/pipermail/tz/2019-March/027829.html This is on Linux. I don't know what's the proper way of doing this on Python/Linux but assert_tz_offset throwing an exception on this time zone is not a good idea
import datetime
import time
import pytz
pytz.timezone('Europe/Dublin')
<DstTzInfo 'Europe/Dublin' LMT-1 day, 23:35:00 STD>
tz = pytz.timezone('Europe/Dublin')
int(datetime.datetime.now(tz).utcoffset().total_seconds())
0
if time.daylight and time.localtime().tm_isdst > 0:
... time.altzone
...
-3600
I don't see the problem, and it seems to be working fine, as far as I can tell. Can you please explain how to replicate the problem?
The problem is that there is an assumption that time.localtime().tm_isdst>0
implies that the offset is time.altzone
and that's probably true for all timezones except Europe/Dublin.
set your timezone to Dublin and check out this output:
>>> time.altzone
-3600
>>> time.daylight
1
>>> time.timezone
0
>>> time.tzname
('GMT', 'IST')
current time is GMT right now in real life
I can't replicate the problem you seem to think there is.
If, as the discussion you link to seems to say, Ireland recently have flipped what is standard and what is altzone, then the time.timezone and time.altzone should also be flipped, and hence there should not be a problem. This has not happened on my system, though, so I can't verify that.
So please demonstrate that there is an actual error, not just a hypothetical one based on how you read the code and guess at the effects.
Hi, the problem is that assert_tz_offset(tz)
which is called from unix.py always fails when your timezone is Europe/Dublin because in get_system_offset() the time.localtime().tm_isdst returns 1 right now because as in the icann database it considers the current GMT to be daylight time zone and the non-daylight zone is the irish standard time (IST) which is observed during the summer, other methods of the time module behave differently and consider GMT to be the non-daylight time (see time.tzname and time.altzone above).
This is not a hypothetical problem, I got here while debugging a service that wouldn't start and ended in your library after following the stacktrace.
I have reproduced this behaviour on linux and windows, but on macOs it behaves consistently and it is not reproduced.
"Hi, the problem is that assert_tz_offset(tz) which is called from unix.py always fails when your timezone is Europe/Dublin"
Does it fail with "ValueError: Timezone offset does not match system offset"?
Did you check that your pytz is updated to the latest version?
"get_system_offset() the time.localtime().tm_isdst returns 1 right now"
Right. So, according to what you say, tm_isdst returns 1 in the winter for Europe/Dublin on your computer. That also means that time.altzone should be in effect. Can you verify that this is the case?
Because if isdst is 1 and altzone is NOT in effect, that I would say is a bug in the operating systems timezone setup. There are plenty of timezones that has isdst a 1 in the summer (although they usually are in the southern hemisphere) and this causes no problems.
We are using pytz 2019.3.
Does it fail with "ValueError: Timezone offset does not match system offset"? Yes
Did you check that your pytz is updated to the latest version?
my pytz version
Name: pytz
Version: 2019.3
Summary: World timezone definitions, modern and historical
Home-page: http://pythonhosted.org/pytz
Author: Stuart Bishop
Author-email: stuart@stuartbishop.net
License: MIT
Location: /usr/lib/python3.7/site-packages
Requires:
Required-by: pyRFC3339, certbot, acme
I don't think it matter though because the root of the problem is an inconsistency between method calls in the time module
tm_isdst returns 1 in the winter for Europe/Dublin on your computer. That also means that time.altzone should be in effect
altzone should be 0 because right now we are on GMT, it returns -3600 instead
There are plenty of timezones that has isdst a 1 in the summer (although they usually are in the southern hemisphere) and this causes no problems.
I think the problem is that there are different opinion on whether Ireland is currently in DST or not and the python time module is not consistent with either of them, time.localtime seems to be sourced from the OS config where GMT is DST and other methods like time.altzone are sourced from somewhere else where IST is the DST
Yeah, you are right, on my Linux virtual box I get time.localtime().tm_isdst
to 1 now, while altzone
is -3600. On my mac box, time.localtime().tm_isdst
is 0, interestingly enough (same altzone, thought).
This is certainly a bug, but it's unclear where that bug is (my bet is on either Linux, or Pythons interpretation of this), but it definitely not going to get fixed any time soon, and it also means that the is_dst flag is useless for the time being. I'll change the way the local DST offset is retrieved.
I can confirm I have the exact same issue and have independently traced in back to the same check: https://github.com/regebro/tzlocal/blob/master/tzlocal/utils.py#L15
Relevant stacktrace:
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/conf.py", line 83, in wrapper
return f(*args, **kwargs)
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/__init__.py", line 53, in parse
data = parser.get_date_data(date_string, date_formats)
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/date.py", line 417, in get_date_data
locale, date_string, date_formats, settings=self._settings)
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/date.py", line 189, in parse
return instance._parse()
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/date.py", line 199, in _parse
date_obj = parser()
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/date.py", line 212, in _try_freshness_parser
return freshness_date_parser.get_date_data(self._get_translated_date(), self._settings)
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/freshness_date_parser.py", line 147, in get_date_data
date, period = self.parse(date_string, settings)
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/freshness_date_parser.py", line 94, in parse
self.now = datetime.now(self.get_local_tz())
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/dateparser/freshness_date_parser.py", line 46, in get_local_tz
return get_localzone()
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/tzlocal/unix.py", line 165, in get_localzone
_cache_tz = _get_localzone()
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/tzlocal/unix.py", line 90, in _get_localzone
utils.assert_tz_offset(tz)
File "/home/jjst/.virtualenvs/scrapy/lib/python3.6/site-packages/tzlocal/utils.py", line 38, in assert_tz_offset
raise ValueError(msg)
ValueError: Timezone offset does not match system offset: 0 != 3600. Please, check your config files.
In [17]: tz = pytz.timezone('Europe/Dublin')
In [18]: int(datetime.datetime.now(tz).utcoffset().total_seconds())
...:
...:
Out[18]: 0
In [19]: time.timezone
Out[19]: 0
In [20]: time.altzone
Out[20]: -3600
In [21]: time.daylight
Out[21]: 1
In [23]: time.localtime().tm_isdst
Out[23]: 1
In [24]: time.daylight and time.localtime().tm_isdst > 0
Out[24]: True
(Linux/Ubuntu 18.04, tzlocal 2.0.0)
It seems this check is making assumptions that cannot be correct for all timezone configurations.
@regebro any idea when this one will get fixed? Thanks!
I can confirm that I am having the same problem, which leads to:
ValueError: Timezone offset does not match system offset: 0 != 3600. Please, check your config files.
To test I have changed Dublin to Amsterdam and problem has disappeared.
Any ideas how to do it without manually switching timezones?
Thanks.