1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2025, Brandon Nielsen
4# All rights reserved.
5#
6# This software may be modified and distributed under the terms
7# of the BSD license. See the LICENSE file for details.
8
9from aniso8601.builders.python import PythonTimeBuilder
10from aniso8601.compat import is_string
11from aniso8601.exceptions import ISOFormatError
12
13
14def parse_timezone(tzstr, builder=PythonTimeBuilder):
15 # tzstr can be Z, ±hh:mm, ±hhmm, ±hh
16 if is_string(tzstr) is False:
17 raise ValueError("Time zone must be string.")
18
19 if len(tzstr) == 1 and tzstr[0] == "Z":
20 return builder.build_timezone(negative=False, Z=True, name=tzstr)
21
22 if len(tzstr) == 6:
23 # ±hh:mm
24 hourstr = tzstr[1:3]
25 minutestr = tzstr[4:6]
26
27 if tzstr[0] == "-" and hourstr == "00" and minutestr == "00":
28 raise ISOFormatError("Negative ISO 8601 time offset must not be 0.")
29 elif len(tzstr) == 5:
30 # ±hhmm
31 hourstr = tzstr[1:3]
32 minutestr = tzstr[3:5]
33
34 if tzstr[0] == "-" and hourstr == "00" and minutestr == "00":
35 raise ISOFormatError("Negative ISO 8601 time offset must not be 0.")
36 elif len(tzstr) == 3:
37 # ±hh
38 hourstr = tzstr[1:3]
39 minutestr = None
40
41 if tzstr[0] == "-" and hourstr == "00":
42 raise ISOFormatError("Negative ISO 8601 time offset must not be 0.")
43 else:
44 raise ISOFormatError('"{0}" is not a valid ISO 8601 time offset.'.format(tzstr))
45
46 for componentstr in [hourstr, minutestr]:
47 if componentstr is not None:
48 if componentstr.isdigit() is False:
49 raise ISOFormatError(
50 '"{0}" is not a valid ISO 8601 time offset.'.format(tzstr)
51 )
52
53 if tzstr[0] == "+":
54 return builder.build_timezone(
55 negative=False, hh=hourstr, mm=minutestr, name=tzstr
56 )
57
58 if tzstr[0] == "-":
59 return builder.build_timezone(
60 negative=True, hh=hourstr, mm=minutestr, name=tzstr
61 )
62
63 raise ISOFormatError('"{0}" is not a valid ISO 8601 time offset.'.format(tzstr))