Created
May 28, 2016 19:05
Compare vobject VTIMEZONEs for pytz and dateutil.tz timezones
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Detect differences between pytz and dateutil.tz.gettz, | |
# by comparing the vobject VTIMEZONEs for each. | |
# | |
# (Might actually be finding problems in vobject's | |
# timezone rule detection.) | |
# | |
# Requirements:: | |
# pip install pytz dateutil vobject | |
import dateutil.tz | |
import os | |
import pytz | |
from vobject.icalendar import TimezoneComponent, __tzidMap | |
OUTPUT_DIR = '/tmp/vtimezone' # set to None to skip writing files | |
#OUTPUT_DIR = None | |
def vtimezones_match(tzname, output_dir=None): | |
"""Returns True if pytz and dateutil have same VTIMEZONE for tzname. | |
Set output_dir to write mismatched VTIMEZONE contents to files, | |
allowing easy directory diff. (Will create one file in output_dir/pytz, | |
and a corresponding file in output_dir/dateutil.) | |
""" | |
pytz_tzinfo = pytz.timezone(tzname) | |
dateutil_tzinfo = dateutil.tz.gettz(tzname) | |
# ignore differences in TZID field (see TimezoneComponent.pickTzid) | |
pytz_tzinfo.tzid = dateutil_tzinfo.tzid = tzname | |
__tzidMap.clear() # reset tzid registry to avoid caching | |
pytz_vtimezone = TimezoneComponent(tzinfo=pytz_tzinfo) | |
pytz_serialized = pytz_vtimezone.serialize() | |
__tzidMap.clear() # reset tzid registry to avoid caching | |
dateutil_vtimezone = TimezoneComponent(tzinfo=dateutil_tzinfo) | |
dateutil_serialized = dateutil_vtimezone.serialize() | |
matches = (pytz_serialized == dateutil_serialized) | |
if output_dir and not matches: | |
# Relies on tzname using slash separators | |
write_file( | |
os.path.join(output_dir, 'pytz', tzname), | |
pytz_serialized) | |
write_file( | |
os.path.join(output_dir, 'dateutil', tzname), | |
dateutil_serialized) | |
return matches | |
def write_file(path, text): | |
"""Writes text to path, creating intermediate dirs if needed""" | |
dirname = os.path.dirname(path) | |
if not os.path.exists(dirname): | |
os.makedirs(dirname) | |
with open(path, 'w') as f: | |
f.write(text.replace('\r\n', '\n')) | |
def get_dateutil_tzdb_version(): | |
"""Return the version of the tzdb files used by dateutil.tz.gettz""" | |
# From the contents of the +VERSION file in the tzdb directory | |
utc = dateutil.tz.gettz('UTC') | |
tzdb_dir = os.path.dirname(utc._filename) | |
version_file = os.path.join(tzdb_dir, '+VERSION') | |
with open(version_file) as f: | |
version = f.read() | |
return version.strip() | |
if __name__ == '__main__': | |
dateutil_version = "%s; tzdb %s" % (dateutil.__version__, | |
get_dateutil_tzdb_version()) | |
print("pytz version: %s" % pytz.__version__) | |
print("dateutil version: %s" % dateutil_version) | |
if OUTPUT_DIR: | |
write_file(os.path.join(OUTPUT_DIR, 'pytz/VERSION'), pytz.__version__) | |
write_file(os.path.join(OUTPUT_DIR, 'dateutil/VERSION'), dateutil_version) | |
print("\nDiffering VTIMEZONEs:") | |
for tzname in pytz.all_timezones: | |
if not vtimezones_match(tzname, output_dir=OUTPUT_DIR): | |
print(tzname) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pytz version: 2016.4 | |
dateutil version: 2.5.3; tzdb 2016d | |
Differing VTIMEZONEs: | |
America/Argentina/Catamarca | |
America/Argentina/ComodRivadavia | |
America/Argentina/La_Rioja | |
America/Argentina/Mendoza | |
America/Argentina/Rio_Gallegos | |
America/Argentina/San_Juan | |
America/Argentina/San_Luis | |
America/Argentina/Tucuman | |
America/Argentina/Ushuaia | |
America/Cambridge_Bay | |
America/Catamarca | |
America/Indiana/Knox | |
America/Indiana/Petersburg | |
America/Indiana/Tell_City | |
America/Indiana/Vincennes | |
America/Indiana/Winamac | |
America/Knox_IN | |
America/Mendoza | |
America/Rankin_Inlet | |
America/Resolute | |
Asia/Anadyr | |
Asia/Kamchatka | |
Asia/Khandyga | |
Asia/Novokuznetsk | |
Asia/Tbilisi | |
Asia/Tomsk | |
Europe/Samara | |
US/Indiana-Starke |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment