text: """
  Module for managing timezone on Windows systems.
  """
  import logging
  from datetime import datetime
  
  from salt.exceptions import CommandExecutionError
  
  try:
      import pytz
  
      HAS_PYTZ = True
  except ImportError:
      HAS_PYTZ = False
  
  log = logging.getLogger(__name__)
  
  # Define the module's virtual name
  __virtualname__ = "timezone"
  
  
  class TzMapper:
      def __init__(self, unix_to_win):
          self.win_to_unix = {k.lower(): v for k, v in unix_to_win.items()}
          self.unix_to_win = {v.lower(): k for k, v in unix_to_win.items()}
  
      def add(self, k, v):
          self.unix_to_win[k.lower()] = v
          self.win_to_unix[v.lower()] = k
  
      def remove(self, k):
          self.win_to_unix.pop(self.unix_to_win.pop(k.lower()).lower())
  
      def get_win(self, key, default=None):
          return self.unix_to_win.get(key.lower(), default)
  
      def get_unix(self, key, default=None):
          return self.win_to_unix.get(key.lower(), default)
  
      def list_win(self):
          return sorted(self.unix_to_win.values())
  
      def list_unix(self):
          return sorted(self.win_to_unix.values())
  
  
  mapper = TzMapper(
      {
          "AUS Central Standard Time": "Australia/Darwin",
          "AUS Eastern Standard Time": "Australia/Sydney",
          "Afghanistan Standard Time": "Asia/Kabul",
          "Alaskan Standard Time": "America/Anchorage",
          "Aleutian Standard Time": "America/Adak",
          "Altai Standard Time": "Asia/Barnaul",
          "Arab Standard Time": "Asia/Riyadh",
          "Arabian Standard Time": "Asia/Dubai",
          "Arabic Standard Time": "Asia/Baghdad",
          "Argentina Standard Time": "America/Buenos_Aires",
          "Astrakhan Standard Time": "Europe/Astrakhan",
          "Atlantic Standard Time": "America/Halifax",
          "Aus Central W. Standard Time": "Australia/Eucla",
          "Azerbaijan Standard Time": "Asia/Baku",
          "Azores Standard Time": "Atlantic/Azores",
          "Bahia Standard Time": "America/Bahia",
          "Bangladesh Standard Time": "Asia/Dhaka",
          "Belarus Standard Time": "Europe/Minsk",
          "Bougainville Standard Time": "Pacific/Bougainville",
          "Canada Central Standard Time": "America/Regina",
          "Cape Verde Standard Time": "Atlantic/Cape_Verde",
          "Caucasus Standard Time": "Asia/Yerevan",
          "Cen. Australia Standard Time": "Australia/Adelaide",
          "Central America Standard Time": "America/Guatemala",
          "Central Asia Standard Time": "Asia/Almaty",
          "Central Brazilian Standard Time": "America/Cuiaba",
          "Central Europe Standard Time": "Europe/Budapest",
          "Central European Standard Time": "Europe/Warsaw",
          "Central Pacific Standard Time": "Pacific/Guadalcanal",
          "Central Standard Time": "America/Chicago",
          "Central Standard Time (Mexico)": "America/Mexico_City",
          "Chatham Islands Standard Time": "Pacific/Chatham",
          "China Standard Time": "Asia/Shanghai",
          "Cuba Standard Time": "America/Havana",
          "Dateline Standard Time": "Etc/GMT+12",
          "E. Africa Standard Time": "Africa/Nairobi",
          "E. Australia Standard Time": "Australia/Brisbane",
          "E. Europe Standard Time": "Europe/Chisinau",
          "E. South America Standard Time": "America/Sao_Paulo",
          "Easter Island Standard Time": "Pacific/Easter",
          "Eastern Standard Time": "America/New_York",
          "Eastern Standard Time (Mexico)": "America/Cancun",
          "Egypt Standard Time": "Africa/Cairo",
          "Ekaterinburg Standard Time": "Asia/Yekaterinburg",
          "FLE Standard Time": "Europe/Kiev",
          "Fiji Standard Time": "Pacific/Fiji",
          "GMT Standard Time": "Europe/London",
          "GTB Standard Time": "Europe/Bucharest",
          "Georgian Standard Time": "Asia/Tbilisi",
          "Greenland Standard Time": "America/Godthab",
          "Greenwich Standard Time": "Atlantic/Reykjavik",
          "Haiti Standard Time": "America/Port-au-Prince",
          "Hawaiian Standard Time": "Pacific/Honolulu",
          "India Standard Time": "Asia/Calcutta",
          "Iran Standard Time": "Asia/Tehran",
          "Israel Standard Time": "Asia/Jerusalem",
          "Jordan Standard Time": "Asia/Amman",
          "Kaliningrad Standard Time": "Europe/Kaliningrad",
          "Korea Standard Time": "Asia/Seoul",
          "Libya Standard Time": "Africa/Tripoli",
          "Line Islands Standard Time": "Pacific/Kiritimati",
          "Lord Howe Standard Time": "Australia/Lord_Howe",
          "Magadan Standard Time": "Asia/Magadan",
          "Magallanes Standard Time": "America/Punta_Arenas",
          "Marquesas Standard Time": "Pacific/Marquesas",
          "Mauritius Standard Time": "Indian/Mauritius",
          "Middle East Standard Time": "Asia/Beirut",
          "Montevideo Standard Time": "America/Montevideo",
          "Morocco Standard Time": "Africa/Casablanca",
          "Mountain Standard Time": "America/Denver",
          "Mountain Standard Time (Mexico)": "America/Chihuahua",
          "Myanmar Standard Time": "Asia/Rangoon",
          "N. Central Asia Standard Time": "Asia/Novosibirsk",
          "Namibia Standard Time": "Africa/Windhoek",
          "Nepal Standard Time": "Asia/Katmandu",
          "New Zealand Standard Time": "Pacific/Auckland",
          "Newfoundland Standard Time": "America/St_Johns",
          "Norfolk Standard Time": "Pacific/Norfolk",
          "North Asia East Standard Time": "Asia/Irkutsk",
          "North Asia Standard Time": "Asia/Krasnoyarsk",
          "North Korea Standard Time": "Asia/Pyongyang",
          "Omsk Standard Time": "Asia/Omsk",
          "Pacific SA Standard Time": "America/Santiago",
          "Pacific Standard Time": "America/Los_Angeles",
          "Pacific Standard Time (Mexico)": "America/Tijuana",
          "Pakistan Standard Time": "Asia/Karachi",
          "Paraguay Standard Time": "America/Asuncion",
          "Romance Standard Time": "Europe/Paris",
          "Russia Time Zone 10": "Asia/Srednekolymsk",
          "Russia Time Zone 11": "Asia/Kamchatka",
          "Russia Time Zone 3": "Europe/Samara",
          "Russian Standard Time": "Europe/Moscow",
          "SA Eastern Standard Time": "America/Cayenne",
          "SA Pacific Standard Time": "America/Bogota",
          "SA Western Standard Time": "America/La_Paz",
          "SE Asia Standard Time": "Asia/Bangkok",
          "Saint Pierre Standard Time": "America/Miquelon",
          "Sakhalin Standard Time": "Asia/Sakhalin",
          "Samoa Standard Time": "Pacific/Apia",
          "Saratov Standard Time": "Europe/Saratov",
          "Singapore Standard Time": "Asia/Singapore",
          "South Africa Standard Time": "Africa/Johannesburg",
          "Sri Lanka Standard Time": "Asia/Colombo",
          "Syria Standard Time": "Asia/Damascus",
          "Taipei Standard Time": "Asia/Taipei",
          "Tasmania Standard Time": "Australia/Hobart",
          "Tocantins Standard Time": "America/Araguaina",
          "Tokyo Standard Time": "Asia/Tokyo",
          "Tomsk Standard Time": "Asia/Tomsk",
          "Tonga Standard Time": "Pacific/Tongatapu",
          "Transbaikal Standard Time": "Asia/Chita",
          "Turkey Standard Time": "Europe/Istanbul",
          "Turks And Caicos Standard Time": "America/Grand_Turk",
          "US Eastern Standard Time": "America/Indianapolis",
          "US Mountain Standard Time": "America/Phoenix",
          "UTC": "Etc/GMT",
          "UTC+12": "Etc/GMT-12",
          "UTC+13": "Etc/GMT-13",
          "UTC-02": "Etc/GMT+2",
          "UTC-08": "Etc/GMT+8",
          "UTC-09": "Etc/GMT+9",
          "UTC-11": "Etc/GMT+11",
          "Ulaanbaatar Standard Time": "Asia/Ulaanbaatar",
          "Venezuela Standard Time": "America/Caracas",
          "Vladivostok Standard Time": "Asia/Vladivostok",
          "W. Australia Standard Time": "Australia/Perth",
          "W. Central Africa Standard Time": "Africa/Lagos",
          "W. Europe Standard Time": "Europe/Berlin",
          "W. Mongolia Standard Time": "Asia/Hovd",
          "West Asia Standard Time": "Asia/Tashkent",
          "West Bank Standard Time": "Asia/Hebron",
          "West Pacific Standard Time": "Pacific/Port_Moresby",
          "Yakutsk Standard Time": "Asia/Yakutsk",
      }
  )
  
  
  def __virtual__():
      """
      Only load on windows
      """
      if not __utils__["platform.is_windows"]():
          return False, "Module win_timezone: Not on Windows client"
      if not HAS_PYTZ:
          return False, "Module win_timezone: pytz not found"
      if not __utils__["path.which"]("tzutil"):
          return False, "Module win_timezone: tzutil not found"
      return __virtualname__
  
  
  def get_zone():
      """
      Get current timezone (i.e. America/Denver)
  
      Returns:
          str: Timezone in unix format
  
      Raises:
          CommandExecutionError: If timezone could not be gathered
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' timezone.get_zone
      """
      cmd = ["tzutil", "/g"]
      res = __salt__["cmd.run_all"](cmd, python_shell=False)
      if res["retcode"] or not res["stdout"]:
          raise CommandExecutionError(
              "tzutil encountered an error getting timezone", info=res
          )
      tz = res["stdout"].lower().strip("_dstoff")
      return mapper.get_unix(tz, "Unknown")
  
  
  def get_offset():
      """
      Get current numeric timezone offset from UTC (i.e. -0700)
  
      Returns:
          str: Offset from UTC
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' timezone.get_offset
      """
      # http://craigglennie.com/programming/python/2013/07/21/working-with-timezones-using-Python-and-pytz-localize-vs-normalize/
      tz_object = pytz.timezone(get_zone())
      utc_time = pytz.utc.localize(datetime.utcnow())
      loc_time = utc_time.astimezone(tz_object)
      norm_time = tz_object.normalize(loc_time)
      return norm_time.strftime("%z")
  
  
  def get_zonecode():
      """
      Get current timezone (i.e. PST, MDT, etc)
  
      Returns:
          str: An abbreviated timezone code
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' timezone.get_zonecode
      """
      tz_object = pytz.timezone(get_zone())
      loc_time = tz_object.localize(datetime.utcnow())
      return loc_time.tzname()
  
  
  def set_zone(timezone):
      """
      Sets the timezone using the tzutil.
  
      Args:
          timezone (str): A valid timezone
  
      Returns:
          bool: ``True`` if successful, otherwise ``False``
  
      Raises:
          CommandExecutionError: If invalid timezone is passed
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' timezone.set_zone 'America/Denver'
      """
      # if it's one of the key's just use it
      if timezone.lower() in mapper.win_to_unix:
          win_zone = timezone
  
      elif timezone.lower() in mapper.unix_to_win:
          # if it's one of the values, use the key
          win_zone = mapper.get_win(timezone)
  
      else:
          # Raise error because it's neither key nor value
          raise CommandExecutionError("Invalid timezone passed: {}".format(timezone))
  
      # Set the value
      cmd = ["tzutil", "/s", win_zone]
      res = __salt__["cmd.run_all"](cmd, python_shell=False)
      if res["retcode"]:
          raise CommandExecutionError(
              "tzutil encountered an error setting " "timezone: {}".format(timezone),
              info=res,
          )
      return zone_compare(timezone)
  
  
  def zone_compare(timezone):
      """
      Compares the given timezone with the machine timezone. Mostly useful for
      running state checks.
  
      Args:
          timezone (str):
              The timezone to compare. This can be in Windows or Unix format. Can
              be any of the values returned by the ``timezone.list`` function
  
      Returns:
          bool: ``True`` if they match, otherwise ``False``
  
      Example:
  
      .. code-block:: bash
  
          salt '*' timezone.zone_compare 'America/Denver'
      """
      # if it's one of the key's just use it
      if timezone.lower() in mapper.win_to_unix:
          check_zone = timezone
  
      elif timezone.lower() in mapper.unix_to_win:
          # if it's one of the values, use the key
          check_zone = mapper.get_win(timezone)
  
      else:
          # Raise error because it's neither key nor value
          raise CommandExecutionError("Invalid timezone passed: {}" "".format(timezone))
  
      return get_zone() == mapper.get_unix(check_zone, "Unknown")
  
  
  def list(unix_style=True):
      """
      Return a list of Timezones that this module supports. These can be in either
      Unix or Windows format.
  
      .. versionadded:: 2018.3.3
  
      Args:
          unix_style (bool):
              ``True`` returns Unix-style timezones. ``False`` returns
              Windows-style timezones. Default is ``True``
  
      Returns:
          list: A list of supported timezones
  
      CLI Example:
  
      .. code-block:: bash
  
          # Unix-style timezones
          salt '*' timezone.list
  
          # Windows-style timezones
          salt '*' timezone.list unix_style=False
      """
      if unix_style:
          return mapper.list_unix()
      else:
          return mapper.list_win()
  
  
  def get_hwclock():
      """
      Get current hardware clock setting (UTC or localtime)
  
      .. note::
          The hardware clock is always local time on Windows so this will always
          return "localtime"
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' timezone.get_hwclock
      """
      # The hardware clock is always localtime on Windows
      return "localtime"
  
  
  def set_hwclock(clock):
      """
      Sets the hardware clock to be either UTC or localtime
  
      .. note::
          The hardware clock is always local time on Windows so this will always
          return ``False``
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' timezone.set_hwclock UTC
      """
      # The hardware clock is always localtime on Windows
      return False
  