import os
import pickle
import zlib
from datetime import datetime, timedelta, timezone, tzinfo
from pathlib import Path
import regex as re
from .timezones import timezone_info_list
[docs]
class StaticTzInfo(tzinfo):
    def __init__(self, name, offset):
        self.__offset = offset
        self.__name = name
[docs]
    def tzname(self, dt):
        return self.__name 
[docs]
    def utcoffset(self, dt):
        return self.__offset 
[docs]
    def dst(self, dt):
        return timedelta(0) 
    def __repr__(self):
        return "<%s '%s'>" % (self.__class__.__name__, self.__name)
[docs]
    def localize(self, dt, is_dst=False):
        if dt.tzinfo is not None:
            raise ValueError("Not naive datetime (tzinfo is already set)")
        return dt.replace(tzinfo=self) 
    def __getinitargs__(self):
        return self.__name, self.__offset 
[docs]
def pop_tz_offset_from_string(date_string, as_offset=True):
    if _search_regex_ignorecase.search(date_string):
        for name, info in _tz_offsets:
            timezone_re = info["regex"]
            timezone_match = timezone_re.search(date_string)
            if timezone_match:
                start, stop = timezone_match.span()
                date_string = date_string[: start + 1] + date_string[stop:]
                return (
                    date_string,
                    StaticTzInfo(name, info["offset"]) if as_offset else name,
                )
    return date_string, None 
[docs]
def word_is_tz(word):
    return bool(_search_regex.match(word)) 
[docs]
def convert_to_local_tz(datetime_obj, datetime_tz_offset):
    return datetime_obj - datetime_tz_offset + local_tz_offset 
[docs]
def build_tz_offsets(search_regex_parts):
    def get_offset(tz_obj, regex, repl="", replw=""):
        return (
            tz_obj[0],
            {
                "regex": re.compile(
                    re.sub(repl, replw, regex % tz_obj[0]), re.IGNORECASE
                ),
                "offset": timedelta(seconds=tz_obj[1]),
            },
        )
    for tz_info in timezone_info_list:
        for regex in tz_info["regex_patterns"]:
            for tz_obj in tz_info["timezones"]:
                search_regex_parts.append(tz_obj[0])
                yield get_offset(tz_obj, regex)
                # alternate patterns
                for replace, replacewith in tz_info.get("replace", []):
                    search_regex_parts.append(re.sub(replace, replacewith, tz_obj[0]))
                    yield get_offset(tz_obj, regex, repl=replace, replw=replacewith) 
[docs]
def get_local_tz_offset():
    offset = datetime.now() - datetime.now(tz=timezone.utc).replace(tzinfo=None)
    offset = timedelta(days=offset.days, seconds=round(offset.seconds, -1))
    return offset 
local_tz_offset = get_local_tz_offset()
_tz_offsets = None
_search_regex = None
_search_regex_ignorecase = None
def _load_offsets(cache_path, current_hash):
    global _tz_offsets, _search_regex, _search_regex_ignorecase
    try:
        with open(cache_path, mode="rb") as file:
            (
                serialized_hash,
                _tz_offsets,
                _search_regex,
                _search_regex_ignorecase,
            ) = pickle.load(file)
            if current_hash is None or current_hash == serialized_hash:
                return
    except (FileNotFoundError, ValueError, TypeError):
        pass
    _search_regex_parts = []
    _tz_offsets = list(build_tz_offsets(_search_regex_parts))
    _search_regex = re.compile("|".join(_search_regex_parts))
    _search_regex_ignorecase = re.compile("|".join(_search_regex_parts), re.IGNORECASE)
    with open(cache_path, mode="wb") as file:
        pickle.dump(
            (current_hash, _tz_offsets, _search_regex, _search_regex_ignorecase),
            file,
            protocol=5,
        )
CACHE_PATH = Path(__file__).parent.joinpath("data", "dateparser_tz_cache.pkl")
if "BUILD_TZ_CACHE" in os.environ:
    current_hash = zlib.crc32(str(timezone_info_list).encode("utf-8"))
else:
    current_hash = None
_load_offsets(CACHE_PATH, current_hash)