示例#1
0
def timezone(zone):
    r''' Return a datetime.tzinfo implementation for the given timezone 
    
    >>> from datetime import datetime, timedelta
    >>> utc = timezone('UTC')
    >>> eastern = timezone('US/Eastern')
    >>> eastern.zone
    'US/Eastern'
    >>> timezone(u'US/Eastern') is eastern
    True
    >>> utc_dt = datetime(2002, 10, 27, 6, 0, 0, tzinfo=utc)
    >>> loc_dt = utc_dt.astimezone(eastern)
    >>> fmt = '%Y-%m-%d %H:%M:%S %Z (%z)'
    >>> loc_dt.strftime(fmt)
    '2002-10-27 01:00:00 EST (-0500)'
    >>> (loc_dt - timedelta(minutes=10)).strftime(fmt)
    '2002-10-27 00:50:00 EST (-0500)'
    >>> eastern.normalize(loc_dt - timedelta(minutes=10)).strftime(fmt)
    '2002-10-27 01:50:00 EDT (-0400)'
    >>> (loc_dt + timedelta(minutes=10)).strftime(fmt)
    '2002-10-27 01:10:00 EST (-0500)'

    Raises UnknownTimeZoneError if passed an unknown zone.

    >>> timezone('Asia/Shangri-La')
    Traceback (most recent call last):
    ...
    UnknownTimeZoneError: 'Asia/Shangri-La'

    >>> timezone(u'\N{TRADE MARK SIGN}')
    Traceback (most recent call last):
    ...
    UnknownTimeZoneError: u'\u2122'
    '''
    if zone.upper() == 'UTC':
        return pytz.utc

    try:
        zone = zone.encode('US-ASCII')
    except UnicodeEncodeError:
        # All valid timezones are ASCII
        raise pytz.UnknownTimeZoneError(zone)

    zone = pytz._unmunge_zone(zone)
    if zone not in pytz._tzinfo_cache:
        if zone in all_timezones:
            pytz._tzinfo_cache[zone] = pytz.build_tzinfo(
                zone, caching_tz_opener(zone))
        else:
            raise pytz.UnknownTimeZoneError(zone)

    return pytz._tzinfo_cache[zone]
示例#2
0
def get_timezone(WindowsZoneName=True):
    """
    Get the TimeZone Name

    if WindowsZoneName is True, then it returns the name used by the Microsoft Windows Platform
    otherwise it returns the Olsen name (used by all other platforms)

    Note: this needs to get tested on Windows
    """
    log = logging.getLogger(__name__)
    localzone = tzlocal.get_localzone()
    if localzone is None:
        log.error('tzlocal did not provide a time zone configuration')
        raise pytz.UnknownTimeZoneError(
            'Cannot find  any time zone configuration')
    else:
        olsen_name = localzone.zone
        if WindowsZoneName:
            try:
                windows_name = tzlocal.windows_tz.tz_win[olsen_name]
                log.info('Mappped Olsen Time Zone Name (' + olsen_name +
                         ') to Windows Time Zone Name (' + windows_name + ')')
                return windows_name
            except LookupError:
                log.error('Unable to map Olsen Time Zone Name (' + olsen_name +
                          ') to Windows Time Zone Name')
                return 'Unknown'
        else:
            return olsen_name
示例#3
0
    def get_localzone(_root='/'):
        """No tzlocal; support basic Linux systems with a TZ variable or an /etc/timezone file"""

        # TZ environment variable?  Either a tzinfo file or a timezone name
        tzenv = os.environ.get('TZ')
        if tzenv:
            if os.path.exists(tzenv):
                with open(tzenv, 'rb') as tzfile:
                    return pytz.tzfile.build_tzinfo('local', tzfile)
            return pytz.timezone(tzenv)

        # /etc/timezone file?
        tzpath = os.path.join(_root, 'etc/timezone')
        if os.path.exists(tzpath):
            with open(tzpath, 'rb') as tzfile:
                tzname = tzfile.read().decode().strip()
            if '#' in tzname:
                # eg. 'Somewhere/Special # The Special Zone'
                tzname = tzname.split('#', 1)[0].strip()
            if ' ' in tzname:
                # eg. 'America/Dawson Creek'.  Not really correct, but we'll handle it
                tzname = tzname.replace(' ', '_')
            return pytz.timezone(tzname)

        raise pytz.UnknownTimeZoneError(
            'Can not find any timezone configuration')
示例#4
0
    def setReleaseDate(self, datetime: dtt.datetime, timezone: str) -> None:
        """ Set the release date for the product providing a Python datetime.

        :param datetime: Python datetime (without any timezone info).
                         You must define the timezone in param 'timezone'!
        :param timezone: Timezone string, see also 'pytz.all_timezones'
        :return: None
        """
        try:
            if not timezone:
                raise pytz.UnknownTimeZoneError("No timezone given.")

            givenZone = pytz.timezone(timezone)  # set the source's timezone
            localizedDatetime = givenZone.localize(datetime)  # make source timezone-aware
            datetimeUTC: dtt.datetime = localizedDatetime.astimezone(pytz.utc)  # convert to UTC

        except pytz.UnknownTimeZoneError as e:
            logger.error("Could not set product release date. Invalid time zone string. %s", e,
                         exc_info=True)

        except Exception as e:
            logger.error("Could not set product release date. %s", e, exc_info=True)

        else:
            self.__releaseDateStamp = datetimeUTC.timestamp()
示例#5
0
    def __init__(self, unit: str_type | DatetimeTZDtype = "ns", tz=None):
        if isinstance(unit, DatetimeTZDtype):
            # error: "str" has no attribute "tz"
            unit, tz = unit.unit, unit.tz  # type: ignore[attr-defined]

        if unit != "ns":
            if isinstance(unit, str) and tz is None:
                # maybe a string like datetime64[ns, tz], which we support for
                # now.
                result = type(self).construct_from_string(unit)
                unit = result.unit
                tz = result.tz
                msg = (f"Passing a dtype alias like 'datetime64[ns, {tz}]' "
                       "to DatetimeTZDtype is no longer supported. Use "
                       "'DatetimeTZDtype.construct_from_string()' instead.")
                raise ValueError(msg)
            else:
                raise ValueError("DatetimeTZDtype only supports ns units")

        if tz:
            tz = timezones.maybe_get_tz(tz)
            tz = timezones.tz_standardize(tz)
        elif tz is not None:
            raise pytz.UnknownTimeZoneError(tz)
        if tz is None:
            raise TypeError("A 'tz' is required.")

        self._unit = unit
        self._tz = tz
示例#6
0
def detect_timezone():
  """Try and detect the timezone that Python is currently running in.
 
  We have a bunch of different methods for trying to figure this out (listed in
  order they are attempted).
    * Try and find /etc/timezone file (with timezone name).
    * Try and find /etc/localtime file (with timezone data).
    * Try and match a TZ to the current dst/offset/shortname.
 
  Returns:
    The detected local timezone as a tzinfo object
 
  Raises:
    pytz.UnknownTimeZoneError: If it was unable to detect a timezone.
  """
 
  tz = _detect_timezone_etc_timezone()
  if tz is not None:
    return tz
 
  tz = _detect_timezone_etc_localtime()
  if tz is not None:
    return tz
 
  # Next we try and use a similiar method to what PHP does.
  # We first try to search on time.tzname, time.timezone, time.daylight to
  # match a pytz zone.
  warnings.warn("Had to fall back to worst detection method (the 'PHP' "
                "method).")
 
  tz = _detect_timezone_php()
  if tz is not None:
    return tz
 
  raise pytz.UnknownTimeZoneError("Unable to detect your timezone!")
示例#7
0
    def __init__(self, unit="ns", tz=None):
        if isinstance(unit, DatetimeTZDtype):
            unit, tz = unit.unit, unit.tz

        if unit != "ns":
            if isinstance(unit, str) and tz is None:
                # maybe a string like datetime64[ns, tz], which we support for
                # now.
                result = type(self).construct_from_string(unit)
                unit = result.unit
                tz = result.tz
                msg = ("Passing a dtype alias like 'datetime64[ns, {tz}]' "
                       "to DatetimeTZDtype is deprecated. Use "
                       "'DatetimeTZDtype.construct_from_string()' instead.")
                warnings.warn(msg.format(tz=tz), FutureWarning, stacklevel=2)
            else:
                raise ValueError("DatetimeTZDtype only supports ns units")

        if tz:
            tz = timezones.maybe_get_tz(tz)
            tz = timezones.tz_standardize(tz)
        elif tz is not None:
            raise pytz.UnknownTimeZoneError(tz)
        elif tz is None:
            raise TypeError("A 'tz' is required.")

        self._unit = unit
        self._tz = tz
示例#8
0
def get_localzone_name():
    # Windows is special. It has unique time zone names (in several
    # meanings of the word) available, but unfortunately, they can be
    # translated to the language of the operating system, so we need to
    # do a backwards lookup, by going through all time zones and see which
    # one matches.
    handle = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)

    TZLOCALKEYNAME = r"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
    localtz = winreg.OpenKey(handle, TZLOCALKEYNAME)
    keyvalues = valuestodict(localtz)
    localtz.Close()
    if 'TimeZoneKeyName' in keyvalues:
        # Windows 7 (and Vista?)

        # For some reason this returns a string with loads of NUL bytes at
        # least on some systems. I don't know if this is a bug somewhere, I
        # just work around it.
        tzkeyname = keyvalues['TimeZoneKeyName'].split('\x00', 1)[0]
    else:
        # Windows 2000 or XP

        # This is the localized name:
        tzwin = keyvalues['StandardName']

        # Open the list of timezones to look up the real name:
        TZKEYNAME = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
        tzkey = winreg.OpenKey(handle, TZKEYNAME)

        # Now, match this value to Time Zone information
        tzkeyname = None
        for i in range(winreg.QueryInfoKey(tzkey)[0]):
            subkey = winreg.EnumKey(tzkey, i)
            sub = winreg.OpenKey(tzkey, subkey)
            data = valuestodict(sub)
            sub.Close()
            if data['Std'] == tzwin:
                tzkeyname = subkey
                break

        tzkey.Close()
        handle.Close()

    if tzkeyname is None:
        raise LookupError('Can not find Windows timezone configuration')

    timezone = win_tz.get(tzkeyname)
    if timezone is None:
        # Nope, that didn't work. Try adding "Standard Time",
        # it seems to work a lot of times:
        timezone = win_tz.get(tzkeyname + " Standard Time")

    # Return what we have.
    if timezone is None:
        raise pytz.UnknownTimeZoneError('Can not find timezone ' + tzkeyname)

    return timezone
示例#9
0
    def __init__(self, unit="ns", tz=None):
        """
        An ExtensionDtype for timezone-aware datetime data.

        Parameters
        ----------
        unit : str, default "ns"
            The precision of the datetime data. Currently limited
            to ``"ns"``.
        tz : str, int, or datetime.tzinfo
            The timezone.

        Raises
        ------
        pytz.UnknownTimeZoneError
            When the requested timezone cannot be found.

        Examples
        --------
        >>> pd.core.dtypes.dtypes.DatetimeTZDtype(tz='UTC')
        datetime64[ns, UTC]

        >>> pd.core.dtypes.dtypes.DatetimeTZDtype(tz='dateutil/US/Central')
        datetime64[ns, tzfile('/usr/share/zoneinfo/US/Central')]
        """
        if isinstance(unit, DatetimeTZDtype):
            unit, tz = unit.unit, unit.tz

        if unit != 'ns':
            if isinstance(unit, str) and tz is None:
                # maybe a string like datetime64[ns, tz], which we support for
                # now.
                result = type(self).construct_from_string(unit)
                unit = result.unit
                tz = result.tz
                msg = (
                    "Passing a dtype alias like 'datetime64[ns, {tz}]' "
                    "to DatetimeTZDtype is deprecated. Use "
                    "'DatetimeTZDtype.construct_from_string()' instead."
                )
                warnings.warn(msg.format(tz=tz), FutureWarning, stacklevel=2)
            else:
                raise ValueError("DatetimeTZDtype only supports ns units")

        if tz:
            tz = timezones.maybe_get_tz(tz)
            tz = timezones.tz_standardize(tz)
        elif tz is not None:
            raise pytz.UnknownTimeZoneError(tz)
        elif tz is None:
            raise TypeError("A 'tz' is required.")

        self._unit = unit
        self._tz = tz
示例#10
0
def get_windows_tz(iana_tz):
    """ Returns a valid windows TimeZone from a given pytz TimeZone (Iana/Olson Timezones)
    Note: Windows Timezones are SHIT!... no ... really THEY ARE HOLY F*****G SHIT!.
    """
    timezone = IANA_TO_WIN.get(
        iana_tz.zone if isinstance(iana_tz, tzinfo) else iana_tz)
    if timezone is None:
        raise pytz.UnknownTimeZoneError("Can't find Iana TimeZone " +
                                        iana_tz.zone)

    return timezone
示例#11
0
def detect_timezone():
    """Try and detect the timezone that Python is currently running in.

  We have a bunch of different methods for trying to figure this out (listed in
  order they are attempted).
    * In windows, use win32timezone.TimeZoneInfo.local()
    * Try TZ environment variable.
    * Try and find /etc/timezone file (with timezone name).
    * Try and find /etc/localtime file (with timezone data).
    * Try and match a TZ to the current dst/offset/shortname.

  Returns:
    The detected local timezone as a tzinfo object

  Raises:
    pytz.UnknownTimeZoneError: If it was unable to detect a timezone.
  """
    if sys.platform == "win32":
        tz = _detect_timezone_windows()
        if tz is not None:
            return tz

    # First we try the TZ variable
    tz = _detect_timezone_environ()
    if tz is not None:
        return tz

    # Second we try /etc/timezone and use the value in that
    tz = _detect_timezone_etc_timezone()
    if tz is not None:
        return tz

    # Next we try and see if something matches the tzinfo in /etc/localtime
    tz = _detect_timezone_etc_localtime()
    if tz is not None:
        return tz

    # Next we try and use a similar method to what PHP does.
    # We first try to search on time.tzname, time.timezone, time.daylight to
    # match a pytz zone.
    warnings.warn("Had to fall back to worst detection method (the 'PHP' "
                  "method).")

    tz = _detect_timezone_php()
    if tz is not None:
        return tz

    raise pytz.UnknownTimeZoneError("Unable to detect your timezone!")
示例#12
0
    def get_iana_tz(windows_tz):
        """ Returns a valid pytz TimeZone (Iana/Olson Timezones) from a given windows TimeZone
        Note: Windows Timezones are SHIT!
        """
        timezone = WIN_TO_IANA.get(windows_tz)
        if timezone is None:
            # Nope, that didn't work. Try adding "Standard Time",
            # it seems to work a lot of times:
            timezone = WIN_TO_IANA.get(windows_tz + ' Standard Time')

        # Return what we have.
        if timezone is None:
            raise pytz.UnknownTimeZoneError("Can't find Windows TimeZone " +
                                            windows_tz)

        return timezone
示例#13
0
def _tz_from_env(tzenv):
    if tzenv[0] == ':':
        tzenv = tzenv[1:]

    # TZ specifies a file
    if os.path.exists(tzenv):
        with open(tzenv, 'rb') as tzfile:
            return pytz.tzfile.build_tzinfo('local', tzfile)

    # TZ specifies a zoneinfo zone.
    try:
        tz = pytz.timezone(tzenv)
        # That worked, so we return this:
        return tz
    except pytz.UnknownTimeZoneError:
        raise pytz.UnknownTimeZoneError(
            "tzlocal() does not support non-zoneinfo timezones like %s. \n"
            "Please use a timezone in the form of Continent/City")
示例#14
0
    def get_localzone( _root='/' ):
        """No tzlocal; support basic Linux systems with a TZ variable or an /etc/timezone file"""
        # /etc/timezone, ... file?
        for tzbase in ( 'etc/timezone',			# Debian, Ubuntu, ...
                        'etc/sysconfig/clock' ):	# RedHat, ...
            tzpath		= os.path.join( _root, tzbase )
            if os.path.exists( tzpath ):
                with open( tzpath, 'rb' ) as tzfile:
                    tzname	= tzfile.read().decode().strip()
                if '#' in tzname:
                    # eg. 'Somewhere/Special # The Special Zone'
                    tzname	= tzname.split( '#', 1 )[0].strip()
                if ' ' in tzname:
                    # eg. 'America/Dawson Creek'.  Not really correct, but we'll handle it
                    tzname	= tzname.replace( ' ', '_' )
                return pytz.timezone( tzname )

        raise pytz.UnknownTimeZoneError( 'Can not find any timezone configuration' )
示例#15
0
def _tzinfome(tzinfo):
  """Gets a tzinfo object from a string.
 
  Args:
    tzinfo: A string (or string like) object, or a datetime.tzinfo object.
 
  Returns:
    An datetime.tzinfo object.
 
  Raises:
    UnknownTimeZoneError: If the timezone given can't be decoded.
  """
  if not isinstance(tzinfo, datetime.tzinfo):
    try:
      tzinfo = pytz.timezone(tzinfo)
    except AttributeError:
      raise pytz.UnknownTimeZoneError("Unknown timezone!")
  return tzinfo
示例#16
0
    def __set_timezone(self) -> Optional[BaseTzInfo]:
        """
        Set timezone as BaseTzInfo from compatible timezone string.

        Raises:
            pytz.UnknownTimeZoneError:

        :raises pytz.UnknownTimeZoneError: If `self.timezone` is not in `list of tz database
            timezones <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>`_.
        :return: A valid timezone
        :rtype: Optional[BaseTzInfo]
        """
        # If timezone is an unsafe string, we will handle a `pytz.UnknownTimeZoneError` exception
        # and pass a friendly message.
        try:
            return pytz.timezone(self.timezone)
        except pytz.UnknownTimeZoneError as unknown_timezone_error:
            raise pytz.UnknownTimeZoneError(
                f"The timezone {self.timezone} is invalid"
                " check valid types here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones"
            ) from unknown_timezone_error
示例#17
0
def get_iana_tz(windows_tz):
    """ Returns a valid pytz TimeZone (Iana/Olson Timezones) from a given
    windows TimeZone

    :param windows_tz: windows format timezone usually returned by
     microsoft api response
    :return:
    :rtype:
    """
    timezone = WIN_TO_IANA.get(windows_tz)
    if timezone is None:
        # Nope, that didn't work. Try adding "Standard Time",
        # it seems to work a lot of times:
        timezone = WIN_TO_IANA.get(windows_tz + ' Standard Time')

    # Return what we have.
    if timezone is None:
        raise pytz.UnknownTimeZoneError("Can't find Windows TimeZone " +
                                        windows_tz)

    return timezone
示例#18
0
def get_timezone():
    '''returns the current timezone specified for the company/facility 
    or the default which is the value in /etc/localtime'''
    global _cached_timezone
    if _cached_timezone:
        return _cached_timezone
    else:
        try:
            company = Transaction().context.get('company')
            company = Pool().get('company.company')(company)
            tz = company.get_timezone
        except:
            tz = None

    if tz:
        _cached_timezone = pytz.timezone(tz)
    elif ospath.exists('/etc/localtime'):
        _cached_timezone = pytz.tzfile.build_tzinfo(
            'local', open('/etc/localtime', 'rb'))
    else:
        raise pytz.UnknownTimeZoneError('Cannot find suitable time zone')

    return _cached_timezone
示例#19
0
def _get_localzone():
    if winreg is None:
        raise pytz.UnknownTimeZoneError('Runtime support not available')
    return pytz.timezone(get_localzone_name())
示例#20
0
def _get_localzone(_root='/'):
    """Tries to find the local timezone configuration.
    This method prefers finding the timezone name and passing that to pytz,
    over passing in the localtime file, as in the later case the zoneinfo
    name is unknown.
    The parameter _root makes the function look for files like /etc/localtime
    beneath the _root directory. This is primarily used by the tests.
    In normal usage you call the function without parameters.
    """

    tzenv = os.environ.get('TZ')
    if tzenv:
        return _tz_from_env(tzenv)

    # This is actually a pretty reliable way to test for the local time
    # zone on operating systems like OS X.  On OS X especially this is the
    # only one that actually works.
    try:
        link_dst = os.readlink('/etc/localtime')
    except OSError:
        pass
    else:
        pos = link_dst.find('/zoneinfo/')
        if pos >= 0:
            zone_name = link_dst[pos + 10:]
            try:
                return pytz.timezone(zone_name)
            except pytz.UnknownTimeZoneError:
                pass

    # If we are on OS X now we are pretty sure that the rest of the
    # code will fail and just fall through until it hits the reading
    # of /etc/localtime and using it without name.  At this point we
    # can invoke systemconfig which internally invokes ICU.  ICU itself
    # does the same thing we do (readlink + compare file contents) but
    # since it knows where the zone files are that should be a bit
    # better than reimplementing the logic here.
    if sys.platform == 'darwin':
        c = subprocess.Popen(['systemsetup', '-gettimezone'],
                             stdout=subprocess.PIPE)
        sys_result = c.communicate()[0]
        c.wait()
        tz_match = _systemconfig_tz.search(sys_result)
        if tz_match is not None:
            zone_name = tz_match.group(1)
            try:
                return pytz.timezone(zone_name)
            except pytz.UnknownTimeZoneError:
                pass

    # Now look for distribution specific configuration files
    # that contain the timezone name.
    tzpath = os.path.join(_root, 'etc/timezone')
    if os.path.exists(tzpath):
        with open(tzpath, 'rb') as tzfile:
            data = tzfile.read()

            # Issue #3 in tzlocal was that /etc/timezone was a zoneinfo file.
            # That's a misconfiguration, but we need to handle it gracefully:
            if data[:5] != 'TZif2':
                etctz = data.strip().decode()
                # Get rid of host definitions and comments:
                if ' ' in etctz:
                    etctz, dummy = etctz.split(' ', 1)
                if '#' in etctz:
                    etctz, dummy = etctz.split('#', 1)
                return pytz.timezone(etctz.replace(' ', '_'))

    # CentOS has a ZONE setting in /etc/sysconfig/clock,
    # OpenSUSE has a TIMEZONE setting in /etc/sysconfig/clock and
    # Gentoo has a TIMEZONE setting in /etc/conf.d/clock
    # We look through these files for a timezone:
    zone_re = re.compile('\s*ZONE\s*=\s*\"')
    timezone_re = re.compile('\s*TIMEZONE\s*=\s*\"')
    end_re = re.compile('\"')

    for filename in ('etc/sysconfig/clock', 'etc/conf.d/clock'):
        tzpath = os.path.join(_root, filename)
        if not os.path.exists(tzpath):
            continue
        with open(tzpath, 'rt') as tzfile:
            for line in tzfile:
                # Look for the ZONE= setting.
                match = zone_re.match(line)
                if match is None:
                    # No ZONE= setting. Look for the TIMEZONE= setting.
                    match = timezone_re.match(line)
                if match is not None:
                    # Some setting existed
                    line = line[match.end():]
                    etctz = line[:end_re.search(line).start()]

                    # We found a timezone
                    return pytz.timezone(etctz.replace(' ', '_'))

    # No explicit setting existed. Use localtime
    for filename in ('etc/localtime', 'usr/local/etc/localtime'):
        tzpath = os.path.join(_root, filename)

        if not os.path.exists(tzpath):
            continue

        with open(tzpath, 'rb') as tzfile:
            return pytz.tzfile.build_tzinfo('local', tzfile)

    raise pytz.UnknownTimeZoneError('Can not find any timezone configuration')
示例#21
0
def _get_localzone(_root='/'):
    """Tries to find the local timezone configuration.

    This method prefers finding the timezone name and passing that to pytz,
    over passing in the localtime file, as in the later case the zoneinfo
    name is unknown.

    The parameter _root makes the function look for files like /etc/localtime
    beneath the _root directory. This is primarily used by the tests.
    In normal usage you call the function without parameters."""

    tzenv = os.environ.get('TZ')
    if tzenv:
        try:
            return _tz_from_env(tzenv)
        except pytz.UnknownTimeZoneError:
            pass

    # Now look for distribution specific configuration files
    # that contain the timezone name.
    for configfile in ('etc/timezone', 'var/db/zoneinfo'):
        tzpath = os.path.join(_root, configfile)
        if os.path.exists(tzpath):
            with open(tzpath, 'rb') as tzfile:
                data = tzfile.read()

                # Issue #3 was that /etc/timezone was a zoneinfo file.
                # That's a misconfiguration, but we need to handle it gracefully:
                if data[:5] != 'TZif2':
                    etctz = data.strip().decode()
                    # Get rid of host definitions and comments:
                    if ' ' in etctz:
                        etctz, dummy = etctz.split(' ', 1)
                    if '#' in etctz:
                        etctz, dummy = etctz.split('#', 1)
                    return pytz.timezone(etctz.replace(' ', '_'))

    # CentOS has a ZONE setting in /etc/sysconfig/clock,
    # OpenSUSE has a TIMEZONE setting in /etc/sysconfig/clock and
    # Gentoo has a TIMEZONE setting in /etc/conf.d/clock
    # We look through these files for a timezone:

    zone_re = re.compile('\s*ZONE\s*=\s*\"')
    timezone_re = re.compile('\s*TIMEZONE\s*=\s*\"')
    end_re = re.compile('\"')

    for filename in ('etc/sysconfig/clock', 'etc/conf.d/clock'):
        tzpath = os.path.join(_root, filename)
        if not os.path.exists(tzpath):
            continue
        with open(tzpath, 'rt') as tzfile:
            data = tzfile.readlines()

        for line in data:
            # Look for the ZONE= setting.
            match = zone_re.match(line)
            if match is None:
                # No ZONE= setting. Look for the TIMEZONE= setting.
                match = timezone_re.match(line)
            if match is not None:
                # Some setting existed
                line = line[match.end():]
                etctz = line[:end_re.search(line).start()]

                # We found a timezone
                return pytz.timezone(etctz.replace(' ', '_'))

    # systemd distributions use symlinks that include the zone name,
    # see manpage of localtime(5) and timedatectl(1)
    tzpath = os.path.join(_root, 'etc/localtime')
    if os.path.exists(tzpath) and os.path.islink(tzpath):
        tzpath = os.path.realpath(tzpath)
        start = tzpath.find("/") + 1
        while start is not 0:
            tzpath = tzpath[start:]
            try:
                return pytz.timezone(tzpath)
            except pytz.UnknownTimeZoneError:
                pass
            start = tzpath.find("/") + 1

    # No explicit setting existed. Use localtime
    for filename in ('etc/localtime', 'usr/local/etc/localtime'):
        tzpath = os.path.join(_root, filename)

        if not os.path.exists(tzpath):
            continue
        with open(tzpath, 'rb') as tzfile:
            return pytz.tzfile.build_tzinfo('local', tzfile)

    raise pytz.UnknownTimeZoneError('Can not find any timezone configuration')
示例#22
0
def _get_localzone(_root='/'):
    """Tries to find the local timezone configuration.

    This method prefers finding the timezone name and passing that to pytz,
    over passing in the localtime file, as in the later case the zoneinfo
    name is unknown.

    The parameter _root makes the function look for files like /etc/localtime
    beneath the _root directory. This is primarily used by the tests.
    In normal usage you call the function without parameters."""

    tzenv = _try_tz_from_env()
    if tzenv:
        return tzenv

    # Now look for distribution specific configuration files
    # that contain the timezone name.
    for configfile in ('etc/timezone', 'var/db/zoneinfo'):
        tzpath = os.path.join(_root, configfile)
        try:
            with open(tzpath, 'rb') as tzfile:
                data = tzfile.read()

                # Issue #3 was that /etc/timezone was a zoneinfo file.
                # That's a misconfiguration, but we need to handle it gracefully:
                if data[:5] == b'TZif2':
                    continue

                etctz = data.strip().decode()
                if not etctz:
                    # Empty file, skip
                    continue
                for etctz in data.decode().splitlines():
                    # Get rid of host definitions and comments:
                    if ' ' in etctz:
                        etctz, dummy = etctz.split(' ', 1)
                    if '#' in etctz:
                        etctz, dummy = etctz.split('#', 1)
                    if not etctz:
                        continue
                    return pytz.timezone(etctz.replace(' ', '_'))
        except IOError:
            # File doesn't exist or is a directory
            continue

    # CentOS has a ZONE setting in /etc/sysconfig/clock,
    # OpenSUSE has a TIMEZONE setting in /etc/sysconfig/clock and
    # Gentoo has a TIMEZONE setting in /etc/conf.d/clock
    # We look through these files for a timezone:

    zone_re = re.compile(r'\s*ZONE\s*=\s*\"')
    timezone_re = re.compile(r'\s*TIMEZONE\s*=\s*\"')
    end_re = re.compile('\"')

    for filename in ('etc/sysconfig/clock', 'etc/conf.d/clock'):
        tzpath = os.path.join(_root, filename)
        try:
            with open(tzpath, 'rt') as tzfile:
                data = tzfile.readlines()

            for line in data:
                # Look for the ZONE= setting.
                match = zone_re.match(line)
                if match is None:
                    # No ZONE= setting. Look for the TIMEZONE= setting.
                    match = timezone_re.match(line)
                if match is not None:
                    # Some setting existed
                    line = line[match.end():]
                    etctz = line[:end_re.search(line).start()]

                    # We found a timezone
                    return pytz.timezone(etctz.replace(' ', '_'))
        except IOError:
            # File doesn't exist or is a directory
            continue

    # systemd distributions use symlinks that include the zone name,
    # see manpage of localtime(5) and timedatectl(1)
    tzpath = os.path.join(_root, 'etc/localtime')
    if os.path.exists(tzpath) and os.path.islink(tzpath):
        tzpath = os.path.realpath(tzpath)
        start = tzpath.find("/") + 1
        while start is not 0:
            tzpath = tzpath[start:]
            try:
                return pytz.timezone(tzpath)
            except pytz.UnknownTimeZoneError:
                pass
            start = tzpath.find("/") + 1

    # Are we under Termux on Android? It's not officially supported, because
    # there is no reasonable way to run tests for this, but let's make an effort.
    if os.path.exists('/system/bin/getprop'):
        import subprocess
        androidtz = subprocess.check_output(
            ['getprop', 'persist.sys.timezone']).strip().decode()
        if androidtz:
            return pytz.timezone(androidtz)
    # on some android devices getprop does not gives any results
    if hasattr(sys, 'getandroidapilevel'):
        try:
            # we are on android and use jnius to get tz in official android supported way
            from jnius import autoclass
            TimeZone = autoclass('java.util.TimeZone')
            androidtz = TimeZone.getDefault().getID()
            return pytz.timezone(androidtz)
        except ImportError:
            # we can't do anything about it
            pass

    # No explicit setting existed. Use localtime
    for filename in ('etc/localtime', 'usr/local/etc/localtime'):
        tzpath = os.path.join(_root, filename)

        if not os.path.exists(tzpath):
            continue
        with open(tzpath, 'rb') as tzfile:
            return pytz.tzfile.build_tzinfo('local', tzfile)

    raise pytz.UnknownTimeZoneError('Can not find any timezone configuration')
示例#23
0
def detect_timezone():
    """Try and detect the timezone that Python is currently running in.

  We have a bunch of different methods for trying to figure this out (listed in
  order they are attempted).
    * In windows, use win32timezone.TimeZoneInfo.local()
    * Try TZ environment variable.
    * Try and find /etc/timezone file (with timezone name).
    * Try and find /etc/localtime file (with timezone data).
    * Try and match a TZ to the current dst/offset/shortname.

  Returns:
    The detected local timezone as a tzinfo object

  Raises:
    pytz.UnknownTimeZoneError: If it was unable to detect a timezone.
  """
    # Windows
    global win32timezone_to_en
    try:
        import win32timezone
        # Try and fetch the key_name for the timezone using Get(Dynamic)TimeZoneInformation
        tzi = DTZI_c()
        kernel32 = ctypes.windll.kernel32
        getter = kernel32.GetTimeZoneInformation
        getter = getattr(kernel32, 'GetDynamicTimeZoneInformation', getter)
        # code is for daylight savings: 0 means disabled/not defined, 1 means enabled but inactive, 2 means enabled and active
        code = getter(ctypes.byref(tzi))
        win32tz_key_name = tzi.key_name
        if not win32tz_key_name:
            # we're on Windows before Vista/Server 2008 - need to look up the standard_name in the registry
            # This will not work in some multilingual setups if running in a language other than the operating system default
            win32tz_name = tzi.standard_name
            if not win32timezone_to_en:
                win32timezone_to_en = dict(
                    win32timezone.TimeZoneInfo._get_indexed_time_zone_keys(
                        "Std"))
            win32tz_key_name = win32timezone_to_en.get(win32tz_name,
                                                       win32tz_name)
        olson_name = win32tz_map.win32timezones.get(win32tz_key_name, None)
        if not olson_name:
            raise ValueError(
                u"Could not map win32 timezone name %s (English %s) to Olson timezone name"
                % (win32tz_name, win32tz_key_name))
        return pytz.timezone(olson_name)
    except ImportError:
        pass

    # First we try the TZ variable
    tz = _detect_timezone_environ()
    if tz is not None:
        return tz

    # Second we try /etc/timezone and use the value in that
    tz = _detect_timezone_etc_timezone()
    if tz is not None:
        return tz

    # Next we try and see if something matches the tzinfo in /etc/localtime
    tz = _detect_timezone_etc_localtime()
    if tz is not None:
        return tz

    # Next we try and use a similiar method to what PHP does.
    # We first try to search on time.tzname, time.timezone, time.daylight to
    # match a pytz zone.
    warnings.warn("Had to fall back to worst detection method (the 'PHP' "
                  "method).")

    tz = _detect_timezone_php()
    if tz is not None:
        return tz

    raise pytz.UnknownTimeZoneError("Unable to detect your timezone!")