1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2021, 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 elif len(tzstr) == 6:
22 # ±hh:mm
23 hourstr = tzstr[1:3]
24 minutestr = tzstr[4:6]
25
26 if tzstr[0] == "-" and hourstr == "00" and minutestr == "00":
27 raise ISOFormatError("Negative ISO 8601 time offset must not " "be 0.")
28 elif len(tzstr) == 5:
29 # ±hhmm
30 hourstr = tzstr[1:3]
31 minutestr = tzstr[3:5]
32
33 if tzstr[0] == "-" and hourstr == "00" and minutestr == "00":
34 raise ISOFormatError("Negative ISO 8601 time offset must not " "be 0.")
35 elif len(tzstr) == 3:
36 # ±hh
37 hourstr = tzstr[1:3]
38 minutestr = None
39
40 if tzstr[0] == "-" and hourstr == "00":
41 raise ISOFormatError("Negative ISO 8601 time offset must not " "be 0.")
42 else:
43 raise ISOFormatError('"{0}" is not a valid ISO 8601 time offset.'.format(tzstr))
44
45 for componentstr in [hourstr, minutestr]:
46 if componentstr is not None:
47 if componentstr.isdigit() is False:
48 raise ISOFormatError(
49 '"{0}" is not a valid ISO 8601 time offset.'.format(tzstr)
50 )
51
52 if tzstr[0] == "+":
53 return builder.build_timezone(
54 negative=False, hh=hourstr, mm=minutestr, name=tzstr
55 )
56
57 if tzstr[0] == "-":
58 return builder.build_timezone(
59 negative=True, hh=hourstr, mm=minutestr, name=tzstr
60 )
61
62 raise ISOFormatError('"{0}" is not a valid ISO 8601 time offset.'.format(tzstr))