# Path: craft_ai/errors.py
# class CraftAiTimeError(CraftAiError):
#     """An error occured during the creation of a craft_ai.Time instance."""
# 
# Path: craft_ai/timezones.py
# def is_timezone(value):
#     # Valid time zone range is -12:00 (-720 min) and +14:00 (+840 min)
#     # cf. https://en.wikipedia.org/wiki/List_of_UTC_time_offsets
#     if isinstance(value, int) and value <= 840 and value >= -720:
#         return True
#     if not isinstance(value, str):
#         return False
#     if value in TIMEZONES:
#         return True
#     result_reg_exp = _TIMEZONE_REGEX.match(value) is not None
#     return result_reg_exp
# 
# def timezone_offset_in_sec(timezone):
#     if isinstance(timezone, int):
#         # If the offset belongs to [-15, 15] it is considered to represent hours.
#         # This reproduces Moment's utcOffset behaviour.
#         if timezone > -16 and timezone < 16:
#             return timezone * 60 * 60
#         return timezone * 60
#     if timezone in TIMEZONES:
#         timezone = TIMEZONES[timezone]
#     if len(timezone) > 3:
#         timezone = timezone.replace(":", "")
#         offset = (int(timezone[-4:-2]) * 60 + int(timezone[-2:])) * 60
#     else:
#         offset = (int(timezone[-2:]) * 60) * 60
# 
#     if timezone[0] == "-":
#         offset = -offset
# 
#     return offset


import time
from datetime import datetime, tzinfo, timedelta
from pytz import utc as pyutc
from tzlocal import get_localzone
from dateutil.parser import isoparse
from craft_ai.errors import CraftAiTimeError
from craft_ai.timezones import is_timezone, timezone_offset_in_sec
            elif isinstance(timestamp, str):
                _time = time_from_string_timestamp_and_timezone(timestamp, timezone)

            else:
                raise CraftAiTimeError(
                    """Unable to instantiate Time from given timestamp."""
                    """ It must be integer or string."""
                )
            return _time

        def set_timezone(timestamp, timezone):
            if isinstance(timezone, tzinfo):
                # If it's already a timezone object, no more work is needed
                _time = timestamp.astimezone(timezone)
            elif is_timezone(timezone):
                # If it's a string, we convert it to a usable timezone object
                offset = timezone_offset_in_sec(timezone)
                _time = timestamp.astimezone(tz=dt_timezone(timedelta(seconds=offset)))
            else:
                raise CraftAiTimeError(
                    """Unable to instantiate Time with the given timezone."""
                    """ {} is neither a string nor a timezone.""".format(timezone)
                )
            return _time

        _time = set_time_and_timezone(t, timezone)

        try:
            self.utc_iso = _time.isoformat()
        except ValueError as e:

# Path: craft_ai/errors.py
# class CraftAiTimeError(CraftAiError):
#     """An error occured during the creation of a craft_ai.Time instance."""
# 
# Path: craft_ai/timezones.py
# def is_timezone(value):
#     # Valid time zone range is -12:00 (-720 min) and +14:00 (+840 min)
#     # cf. https://en.wikipedia.org/wiki/List_of_UTC_time_offsets
#     if isinstance(value, int) and value <= 840 and value >= -720:
#         return True
#     if not isinstance(value, str):
#         return False
#     if value in TIMEZONES:
#         return True
#     result_reg_exp = _TIMEZONE_REGEX.match(value) is not None
#     return result_reg_exp
# 
# def timezone_offset_in_sec(timezone):
#     if isinstance(timezone, int):
#         # If the offset belongs to [-15, 15] it is considered to represent hours.
#         # This reproduces Moment's utcOffset behaviour.
#         if timezone > -16 and timezone < 16:
#             return timezone * 60 * 60
#         return timezone * 60
#     if timezone in TIMEZONES:
#         timezone = TIMEZONES[timezone]
#     if len(timezone) > 3:
#         timezone = timezone.replace(":", "")
#         offset = (int(timezone[-4:-2]) * 60 + int(timezone[-2:])) * 60
#     else:
#         offset = (int(timezone[-2:]) * 60) * 60
# 
#     if timezone[0] == "-":
#         offset = -offset
# 
#     return offset


# Path: craft_ai/time.py
import time
from datetime import datetime, tzinfo, timedelta
from pytz import utc as pyutc
from tzlocal import get_localzone
from dateutil.parser import isoparse
from craft_ai.errors import CraftAiTimeError
from craft_ai.timezones import is_timezone, timezone_offset_in_sec

            elif isinstance(timestamp, str):
                _time = time_from_string_timestamp_and_timezone(timestamp, timezone)

            else:
                raise CraftAiTimeError(
                    """Unable to instantiate Time from given timestamp."""
                    """ It must be integer or string."""
                )
            return _time

        def set_timezone(timestamp, timezone):
            if isinstance(timezone, tzinfo):
                # If it's already a timezone object, no more work is needed
                _time = timestamp.astimezone(timezone)
            elif is_timezone(timezone):
                # If it's a string, we convert it to a usable timezone object
                offset = timezone_offset_in_sec(timezone)
                _time = timestamp.astimezone(tz=dt_timezone(timedelta(seconds=offset)))
            else:
                raise CraftAiTimeError(
                    """Unable to instantiate Time with the given timezone."""
                    """ {} is neither a string nor a timezone.""".format(timezone)
                )
            return _time

        _time = set_time_and_timezone(t, timezone)

        try:
            self.utc_iso = _time.isoformat()
        except ValueError as e:

            raise CraftAiTimeError(