1from geopy.exc import GeocoderParseError 2 3try: 4 import pytz 5 pytz_available = True 6except ImportError: 7 pytz_available = False 8 9 10__all__ = ( 11 "Timezone", 12) 13 14 15def ensure_pytz_is_installed(): 16 if not pytz_available: 17 raise ImportError( 18 'pytz must be installed in order to locate timezones. ' 19 'If geopy has been installed with `pip`, then pytz can be ' 20 'installed with `pip install "geopy[timezone]"`.' 21 ) 22 23 24def from_timezone_name(timezone_name, raw): 25 ensure_pytz_is_installed() 26 try: 27 pytz_timezone = pytz.timezone(timezone_name) 28 except pytz.UnknownTimeZoneError: 29 raise GeocoderParseError( 30 "pytz could not parse the timezone identifier (%s) " 31 "returned by the service." % timezone_name 32 ) 33 except KeyError: 34 raise GeocoderParseError( 35 "geopy could not find a timezone in this response: %s" % 36 raw 37 ) 38 return Timezone(pytz_timezone, raw) 39 40 41def from_fixed_gmt_offset(gmt_offset_hours, raw): 42 ensure_pytz_is_installed() 43 pytz_timezone = pytz.FixedOffset(gmt_offset_hours * 60) 44 return Timezone(pytz_timezone, raw) 45 46 47class Timezone: 48 """ 49 Contains a parsed response for a timezone request, which is 50 implemented in few geocoders which provide such lookups. 51 """ 52 53 __slots__ = ("_pytz_timezone", "_raw") 54 55 def __init__(self, pytz_timezone, raw): 56 self._pytz_timezone = pytz_timezone 57 self._raw = raw 58 59 @property 60 def pytz_timezone(self): 61 """ 62 pytz timezone instance. 63 64 :rtype: :class:`pytz.tzinfo.BaseTzInfo` 65 """ 66 return self._pytz_timezone 67 68 @property 69 def raw(self): 70 """ 71 Timezone's raw, unparsed geocoder response. For details on this, 72 consult the service's documentation. 73 74 :rtype: dict 75 """ 76 return self._raw 77 78 def __str__(self): 79 return str(self._pytz_timezone) 80 81 def __repr__(self): 82 return "Timezone(%s)" % repr(self.pytz_timezone) 83 84 def __getstate__(self): 85 return self._pytz_timezone, self._raw 86 87 def __setstate__(self, state): 88 self._pytz_timezone, self._raw = state 89 90 def __eq__(self, other): 91 return ( 92 isinstance(other, Timezone) and 93 self._pytz_timezone == other._pytz_timezone and 94 self.raw == other.raw 95 ) 96 97 def __ne__(self, other): 98 return not (self == other) 99