Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/arrow/factory.py: 26%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Implements the :class:`ArrowFactory <arrow.factory.ArrowFactory>` class,
3providing factory methods for common :class:`Arrow <arrow.arrow.Arrow>`
4construction scenarios.
6"""
8import calendar
9from datetime import date, datetime, timezone
10from datetime import tzinfo as dt_tzinfo
11from decimal import Decimal
12from time import struct_time
13from typing import Any, List, Optional, Tuple, Type, Union, overload
15from arrow import parser
16from arrow.arrow import TZ_EXPR, Arrow
17from arrow.constants import DEFAULT_LOCALE
18from arrow.util import is_timestamp, iso_to_gregorian
21class ArrowFactory:
22 """A factory for generating :class:`Arrow <arrow.arrow.Arrow>` objects.
24 :param type: (optional) the :class:`Arrow <arrow.arrow.Arrow>`-based class to construct from.
25 Defaults to :class:`Arrow <arrow.arrow.Arrow>`.
27 """
29 type: Type[Arrow]
31 def __init__(self, type: Type[Arrow] = Arrow) -> None:
32 self.type = type
34 @overload
35 def get(
36 self,
37 *,
38 locale: str = DEFAULT_LOCALE,
39 tzinfo: Optional[TZ_EXPR] = None,
40 normalize_whitespace: bool = False,
41 ) -> Arrow: ... # pragma: no cover
43 @overload
44 def get(
45 self,
46 __obj: Union[
47 Arrow,
48 datetime,
49 date,
50 struct_time,
51 dt_tzinfo,
52 int,
53 float,
54 str,
55 Tuple[int, int, int],
56 ],
57 *,
58 locale: str = DEFAULT_LOCALE,
59 tzinfo: Optional[TZ_EXPR] = None,
60 normalize_whitespace: bool = False,
61 ) -> Arrow: ... # pragma: no cover
63 @overload
64 def get(
65 self,
66 __arg1: Union[datetime, date],
67 __arg2: TZ_EXPR,
68 *,
69 locale: str = DEFAULT_LOCALE,
70 tzinfo: Optional[TZ_EXPR] = None,
71 normalize_whitespace: bool = False,
72 ) -> Arrow: ... # pragma: no cover
74 @overload
75 def get(
76 self,
77 __arg1: str,
78 __arg2: Union[str, List[str]],
79 *,
80 locale: str = DEFAULT_LOCALE,
81 tzinfo: Optional[TZ_EXPR] = None,
82 normalize_whitespace: bool = False,
83 ) -> Arrow: ... # pragma: no cover
85 def get(self, *args: Any, **kwargs: Any) -> Arrow:
86 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object based on flexible inputs.
88 :param locale: (optional) a ``str`` specifying a locale for the parser. Defaults to 'en-us'.
89 :param tzinfo: (optional) a :ref:`timezone expression <tz-expr>` or tzinfo object.
90 Replaces the timezone unless using an input form that is explicitly UTC or specifies
91 the timezone in a positional argument. Defaults to UTC.
92 :param normalize_whitespace: (optional) a ``bool`` specifying whether or not to normalize
93 redundant whitespace (spaces, tabs, and newlines) in a datetime string before parsing.
94 Defaults to false.
96 Usage::
98 >>> import arrow
100 **No inputs** to get current UTC time::
102 >>> arrow.get()
103 <Arrow [2013-05-08T05:51:43.316458+00:00]>
105 **One** :class:`Arrow <arrow.arrow.Arrow>` object, to get a copy.
107 >>> arw = arrow.utcnow()
108 >>> arrow.get(arw)
109 <Arrow [2013-10-23T15:21:54.354846+00:00]>
111 **One** ``float`` or ``int``, convertible to a floating-point timestamp, to get
112 that timestamp in UTC::
114 >>> arrow.get(1367992474.293378)
115 <Arrow [2013-05-08T05:54:34.293378+00:00]>
117 >>> arrow.get(1367992474)
118 <Arrow [2013-05-08T05:54:34+00:00]>
120 **One** ISO 8601-formatted ``str``, to parse it::
122 >>> arrow.get('2013-09-29T01:26:43.830580')
123 <Arrow [2013-09-29T01:26:43.830580+00:00]>
125 **One** ISO 8601-formatted ``str``, in basic format, to parse it::
127 >>> arrow.get('20160413T133656.456289')
128 <Arrow [2016-04-13T13:36:56.456289+00:00]>
130 **One** ``tzinfo``, to get the current time **converted** to that timezone::
132 >>> arrow.get(tz.tzlocal())
133 <Arrow [2013-05-07T22:57:28.484717-07:00]>
135 **One** naive ``datetime``, to get that datetime in UTC::
137 >>> arrow.get(datetime(2013, 5, 5))
138 <Arrow [2013-05-05T00:00:00+00:00]>
140 **One** aware ``datetime``, to get that datetime::
142 >>> arrow.get(datetime(2013, 5, 5, tzinfo=tz.tzlocal()))
143 <Arrow [2013-05-05T00:00:00-07:00]>
145 **One** naive ``date``, to get that date in UTC::
147 >>> arrow.get(date(2013, 5, 5))
148 <Arrow [2013-05-05T00:00:00+00:00]>
150 **One** time.struct time::
152 >>> arrow.get(gmtime(0))
153 <Arrow [1970-01-01T00:00:00+00:00]>
155 **One** iso calendar ``tuple``, to get that week date in UTC::
157 >>> arrow.get((2013, 18, 7))
158 <Arrow [2013-05-05T00:00:00+00:00]>
160 **Two** arguments, a naive or aware ``datetime``, and a replacement
161 :ref:`timezone expression <tz-expr>`::
163 >>> arrow.get(datetime(2013, 5, 5), 'US/Pacific')
164 <Arrow [2013-05-05T00:00:00-07:00]>
166 **Two** arguments, a naive ``date``, and a replacement
167 :ref:`timezone expression <tz-expr>`::
169 >>> arrow.get(date(2013, 5, 5), 'US/Pacific')
170 <Arrow [2013-05-05T00:00:00-07:00]>
172 **Two** arguments, both ``str``, to parse the first according to the format of the second::
174 >>> arrow.get('2013-05-05 12:30:45 America/Chicago', 'YYYY-MM-DD HH:mm:ss ZZZ')
175 <Arrow [2013-05-05T12:30:45-05:00]>
177 **Two** arguments, first a ``str`` to parse and second a ``list`` of formats to try::
179 >>> arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'YYYY-MM-DD HH:mm:ss'])
180 <Arrow [2013-05-05T12:30:45+00:00]>
182 **Three or more** arguments, as for the direct constructor of an ``Arrow`` object::
184 >>> arrow.get(2013, 5, 5, 12, 30, 45)
185 <Arrow [2013-05-05T12:30:45+00:00]>
187 """
189 arg_count = len(args)
190 locale = kwargs.pop("locale", DEFAULT_LOCALE)
191 tz = kwargs.get("tzinfo", None)
192 normalize_whitespace = kwargs.pop("normalize_whitespace", False)
194 # if kwargs given, send to constructor unless only tzinfo provided
195 if len(kwargs) > 1:
196 arg_count = 3
198 # tzinfo kwarg is not provided
199 if len(kwargs) == 1 and tz is None:
200 arg_count = 3
202 # () -> now, @ tzinfo or utc
203 if arg_count == 0:
204 if isinstance(tz, str):
205 tz = parser.TzinfoParser.parse(tz)
206 return self.type.now(tzinfo=tz)
208 if isinstance(tz, dt_tzinfo):
209 return self.type.now(tzinfo=tz)
211 return self.type.utcnow()
213 if arg_count == 1:
214 arg = args[0]
215 if isinstance(arg, Decimal):
216 arg = float(arg)
218 # (None) -> raises an exception
219 if arg is None:
220 raise TypeError("Cannot parse argument of type None.")
222 # try (int, float) -> from timestamp @ tzinfo
223 elif not isinstance(arg, str) and is_timestamp(arg):
224 if tz is None:
225 # set to UTC by default
226 tz = timezone.utc
227 return self.type.fromtimestamp(arg, tzinfo=tz)
229 # (Arrow) -> from the object's datetime @ tzinfo
230 elif isinstance(arg, Arrow):
231 return self.type.fromdatetime(arg.datetime, tzinfo=tz)
233 # (datetime) -> from datetime @ tzinfo
234 elif isinstance(arg, datetime):
235 return self.type.fromdatetime(arg, tzinfo=tz)
237 # (date) -> from date @ tzinfo
238 elif isinstance(arg, date):
239 return self.type.fromdate(arg, tzinfo=tz)
241 # (tzinfo) -> now @ tzinfo
242 elif isinstance(arg, dt_tzinfo):
243 return self.type.now(tzinfo=arg)
245 # (str) -> parse @ tzinfo
246 elif isinstance(arg, str):
247 dt = parser.DateTimeParser(locale).parse_iso(arg, normalize_whitespace)
248 return self.type.fromdatetime(dt, tzinfo=tz)
250 # (struct_time) -> from struct_time
251 elif isinstance(arg, struct_time):
252 return self.type.utcfromtimestamp(calendar.timegm(arg))
254 # (iso calendar) -> convert then from date @ tzinfo
255 elif isinstance(arg, tuple) and len(arg) == 3:
256 d = iso_to_gregorian(*arg)
257 return self.type.fromdate(d, tzinfo=tz)
259 else:
260 raise TypeError(f"Cannot parse single argument of type {type(arg)!r}.")
262 elif arg_count == 2:
263 arg_1, arg_2 = args[0], args[1]
265 if isinstance(arg_1, datetime):
266 # (datetime, tzinfo/str) -> fromdatetime @ tzinfo
267 if isinstance(arg_2, (dt_tzinfo, str)):
268 return self.type.fromdatetime(arg_1, tzinfo=arg_2)
269 else:
270 raise TypeError(
271 f"Cannot parse two arguments of types 'datetime', {type(arg_2)!r}."
272 )
274 elif isinstance(arg_1, date):
275 # (date, tzinfo/str) -> fromdate @ tzinfo
276 if isinstance(arg_2, (dt_tzinfo, str)):
277 return self.type.fromdate(arg_1, tzinfo=arg_2)
278 else:
279 raise TypeError(
280 f"Cannot parse two arguments of types 'date', {type(arg_2)!r}."
281 )
283 # (str, format) -> parse @ tzinfo
284 elif isinstance(arg_1, str) and isinstance(arg_2, (str, list)):
285 dt = parser.DateTimeParser(locale).parse(
286 args[0], args[1], normalize_whitespace
287 )
288 return self.type.fromdatetime(dt, tzinfo=tz)
290 else:
291 raise TypeError(
292 f"Cannot parse two arguments of types {type(arg_1)!r} and {type(arg_2)!r}."
293 )
295 # 3+ args -> datetime-like via constructor
296 else:
297 return self.type(*args, **kwargs)
299 def utcnow(self) -> Arrow:
300 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in UTC time.
302 Usage::
304 >>> import arrow
305 >>> arrow.utcnow()
306 <Arrow [2013-05-08T05:19:07.018993+00:00]>
307 """
309 return self.type.utcnow()
311 def now(self, tz: Optional[TZ_EXPR] = None) -> Arrow:
312 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in the given
313 timezone.
315 :param tz: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to local time.
317 Usage::
319 >>> import arrow
320 >>> arrow.now()
321 <Arrow [2013-05-07T22:19:11.363410-07:00]>
323 >>> arrow.now('US/Pacific')
324 <Arrow [2013-05-07T22:19:15.251821-07:00]>
326 >>> arrow.now('+02:00')
327 <Arrow [2013-05-08T07:19:25.618646+02:00]>
329 >>> arrow.now('local')
330 <Arrow [2013-05-07T22:19:39.130059-07:00]>
331 """
333 if tz is None:
334 tz = datetime.now().astimezone().tzinfo
335 elif not isinstance(tz, dt_tzinfo):
336 tz = parser.TzinfoParser.parse(tz)
338 return self.type.now(tz)