_helpers.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. try:
  2. import pytz
  3. except ModuleNotFoundError:
  4. pytz = None
  5. try:
  6. import zoneinfo
  7. except ModuleNotFoundError:
  8. zoneinfo = None
  9. def _get_tzinfo(tzenv: str):
  10. """Get the tzinfo from `zoneinfo` or `pytz`
  11. :param tzenv: timezone in the form of Continent/City
  12. :return: tzinfo object or None if not found
  13. """
  14. if pytz:
  15. try:
  16. return pytz.timezone(tzenv)
  17. except pytz.UnknownTimeZoneError:
  18. pass
  19. else:
  20. try:
  21. return zoneinfo.ZoneInfo(tzenv)
  22. except ValueError as ve:
  23. # This is somewhat hacky, but since _validate_tzfile_path() doesn't
  24. # raise a specific error type, we'll need to check the message to be
  25. # one we know to be from that function.
  26. # If so, we pretend it meant that the TZ didn't exist, for the benefit
  27. # of `babel.localtime` catching the `LookupError` raised by
  28. # `_get_tzinfo_or_raise()`.
  29. # See https://github.com/python-babel/babel/issues/1092
  30. if str(ve).startswith("ZoneInfo keys "):
  31. return None
  32. except zoneinfo.ZoneInfoNotFoundError:
  33. pass
  34. return None
  35. def _get_tzinfo_or_raise(tzenv: str):
  36. tzinfo = _get_tzinfo(tzenv)
  37. if tzinfo is None:
  38. raise LookupError(
  39. f"Can not find timezone {tzenv}. \n"
  40. "Timezone names are generally in the form `Continent/City`.",
  41. )
  42. return tzinfo
  43. def _get_tzinfo_from_file(tzfilename: str):
  44. with open(tzfilename, 'rb') as tzfile:
  45. if pytz:
  46. return pytz.tzfile.build_tzinfo('local', tzfile)
  47. else:
  48. return zoneinfo.ZoneInfo.from_file(tzfile)