Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/arrow/factory.py: 30%
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
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 dateutil import tz as dateutil_tz
17from arrow import parser
18from arrow.arrow import TZ_EXPR, Arrow
19from arrow.constants import DEFAULT_LOCALE
20from arrow.util import is_timestamp, iso_to_gregorian
23class ArrowFactory:
24 """A factory for generating :class:`Arrow <arrow.arrow.Arrow>` objects.
26 :param type: (optional) the :class:`Arrow <arrow.arrow.Arrow>`-based class to construct from.
27 Defaults to :class:`Arrow <arrow.arrow.Arrow>`.
29 """
31 type: Type[Arrow]
33 def __init__(self, type: Type[Arrow] = Arrow) -> None:
34 self.type = type
36 @overload
37 def get(
38 self,
39 *,
40 locale: str = DEFAULT_LOCALE,
41 tzinfo: Optional[TZ_EXPR] = None,
42 normalize_whitespace: bool = False,
43 ) -> Arrow:
44 ... # pragma: no cover
46 @overload
47 def get(
48 self,
49 __obj: Union[
50 Arrow,
51 datetime,
52 date,
53 struct_time,
54 dt_tzinfo,
55 int,
56 float,
57 str,
58 Tuple[int, int, int],
59 ],
60 *,
61 locale: str = DEFAULT_LOCALE,
62 tzinfo: Optional[TZ_EXPR] = None,
63 normalize_whitespace: bool = False,
64 ) -> Arrow:
65 ... # pragma: no cover
67 @overload
68 def get(
69 self,
70 __arg1: Union[datetime, date],
71 __arg2: TZ_EXPR,
72 *,
73 locale: str = DEFAULT_LOCALE,
74 tzinfo: Optional[TZ_EXPR] = None,
75 normalize_whitespace: bool = False,
76 ) -> Arrow:
77 ... # pragma: no cover
79 @overload
80 def get(
81 self,
82 __arg1: str,
83 __arg2: Union[str, List[str]],
84 *,
85 locale: str = DEFAULT_LOCALE,
86 tzinfo: Optional[TZ_EXPR] = None,
87 normalize_whitespace: bool = False,
88 ) -> Arrow:
89 ... # pragma: no cover
91 def get(self, *args: Any, **kwargs: Any) -> Arrow:
92 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object based on flexible inputs.
94 :param locale: (optional) a ``str`` specifying a locale for the parser. Defaults to 'en-us'.
95 :param tzinfo: (optional) a :ref:`timezone expression <tz-expr>` or tzinfo object.
96 Replaces the timezone unless using an input form that is explicitly UTC or specifies
97 the timezone in a positional argument. Defaults to UTC.
98 :param normalize_whitespace: (optional) a ``bool`` specifying whether or not to normalize
99 redundant whitespace (spaces, tabs, and newlines) in a datetime string before parsing.
100 Defaults to false.
102 Usage::
104 >>> import arrow
106 **No inputs** to get current UTC time::
108 >>> arrow.get()
109 <Arrow [2013-05-08T05:51:43.316458+00:00]>
111 **One** :class:`Arrow <arrow.arrow.Arrow>` object, to get a copy.
113 >>> arw = arrow.utcnow()
114 >>> arrow.get(arw)
115 <Arrow [2013-10-23T15:21:54.354846+00:00]>
117 **One** ``float`` or ``int``, convertible to a floating-point timestamp, to get
118 that timestamp in UTC::
120 >>> arrow.get(1367992474.293378)
121 <Arrow [2013-05-08T05:54:34.293378+00:00]>
123 >>> arrow.get(1367992474)
124 <Arrow [2013-05-08T05:54:34+00:00]>
126 **One** ISO 8601-formatted ``str``, to parse it::
128 >>> arrow.get('2013-09-29T01:26:43.830580')
129 <Arrow [2013-09-29T01:26:43.830580+00:00]>
131 **One** ISO 8601-formatted ``str``, in basic format, to parse it::
133 >>> arrow.get('20160413T133656.456289')
134 <Arrow [2016-04-13T13:36:56.456289+00:00]>
136 **One** ``tzinfo``, to get the current time **converted** to that timezone::
138 >>> arrow.get(tz.tzlocal())
139 <Arrow [2013-05-07T22:57:28.484717-07:00]>
141 **One** naive ``datetime``, to get that datetime in UTC::
143 >>> arrow.get(datetime(2013, 5, 5))
144 <Arrow [2013-05-05T00:00:00+00:00]>
146 **One** aware ``datetime``, to get that datetime::
148 >>> arrow.get(datetime(2013, 5, 5, tzinfo=tz.tzlocal()))
149 <Arrow [2013-05-05T00:00:00-07:00]>
151 **One** naive ``date``, to get that date in UTC::
153 >>> arrow.get(date(2013, 5, 5))
154 <Arrow [2013-05-05T00:00:00+00:00]>
156 **One** time.struct time::
158 >>> arrow.get(gmtime(0))
159 <Arrow [1970-01-01T00:00:00+00:00]>
161 **One** iso calendar ``tuple``, to get that week date in UTC::
163 >>> arrow.get((2013, 18, 7))
164 <Arrow [2013-05-05T00:00:00+00:00]>
166 **Two** arguments, a naive or aware ``datetime``, and a replacement
167 :ref:`timezone expression <tz-expr>`::
169 >>> arrow.get(datetime(2013, 5, 5), 'US/Pacific')
170 <Arrow [2013-05-05T00:00:00-07:00]>
172 **Two** arguments, a naive ``date``, and a replacement
173 :ref:`timezone expression <tz-expr>`::
175 >>> arrow.get(date(2013, 5, 5), 'US/Pacific')
176 <Arrow [2013-05-05T00:00:00-07:00]>
178 **Two** arguments, both ``str``, to parse the first according to the format of the second::
180 >>> arrow.get('2013-05-05 12:30:45 America/Chicago', 'YYYY-MM-DD HH:mm:ss ZZZ')
181 <Arrow [2013-05-05T12:30:45-05:00]>
183 **Two** arguments, first a ``str`` to parse and second a ``list`` of formats to try::
185 >>> arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'YYYY-MM-DD HH:mm:ss'])
186 <Arrow [2013-05-05T12:30:45+00:00]>
188 **Three or more** arguments, as for the direct constructor of an ``Arrow`` object::
190 >>> arrow.get(2013, 5, 5, 12, 30, 45)
191 <Arrow [2013-05-05T12:30:45+00:00]>
193 """
195 arg_count = len(args)
196 locale = kwargs.pop("locale", DEFAULT_LOCALE)
197 tz = kwargs.get("tzinfo", None)
198 normalize_whitespace = kwargs.pop("normalize_whitespace", False)
200 # if kwargs given, send to constructor unless only tzinfo provided
201 if len(kwargs) > 1:
202 arg_count = 3
204 # tzinfo kwarg is not provided
205 if len(kwargs) == 1 and tz is None:
206 arg_count = 3
208 # () -> now, @ tzinfo or utc
209 if arg_count == 0:
210 if isinstance(tz, str):
211 tz = parser.TzinfoParser.parse(tz)
212 return self.type.now(tzinfo=tz)
214 if isinstance(tz, dt_tzinfo):
215 return self.type.now(tzinfo=tz)
217 return self.type.utcnow()
219 if arg_count == 1:
220 arg = args[0]
221 if isinstance(arg, Decimal):
222 arg = float(arg)
224 # (None) -> raises an exception
225 if arg is None:
226 raise TypeError("Cannot parse argument of type None.")
228 # try (int, float) -> from timestamp @ tzinfo
229 elif not isinstance(arg, str) and is_timestamp(arg):
230 if tz is None:
231 # set to UTC by default
232 tz = dateutil_tz.tzutc()
233 return self.type.fromtimestamp(arg, tzinfo=tz)
235 # (Arrow) -> from the object's datetime @ tzinfo
236 elif isinstance(arg, Arrow):
237 return self.type.fromdatetime(arg.datetime, tzinfo=tz)
239 # (datetime) -> from datetime @ tzinfo
240 elif isinstance(arg, datetime):
241 return self.type.fromdatetime(arg, tzinfo=tz)
243 # (date) -> from date @ tzinfo
244 elif isinstance(arg, date):
245 return self.type.fromdate(arg, tzinfo=tz)
247 # (tzinfo) -> now @ tzinfo
248 elif isinstance(arg, dt_tzinfo):
249 return self.type.now(tzinfo=arg)
251 # (str) -> parse @ tzinfo
252 elif isinstance(arg, str):
253 dt = parser.DateTimeParser(locale).parse_iso(arg, normalize_whitespace)
254 return self.type.fromdatetime(dt, tzinfo=tz)
256 # (struct_time) -> from struct_time
257 elif isinstance(arg, struct_time):
258 return self.type.utcfromtimestamp(calendar.timegm(arg))
260 # (iso calendar) -> convert then from date @ tzinfo
261 elif isinstance(arg, tuple) and len(arg) == 3:
262 d = iso_to_gregorian(*arg)
263 return self.type.fromdate(d, tzinfo=tz)
265 else:
266 raise TypeError(f"Cannot parse single argument of type {type(arg)!r}.")
268 elif arg_count == 2:
269 arg_1, arg_2 = args[0], args[1]
271 if isinstance(arg_1, datetime):
272 # (datetime, tzinfo/str) -> fromdatetime @ tzinfo
273 if isinstance(arg_2, (dt_tzinfo, str)):
274 return self.type.fromdatetime(arg_1, tzinfo=arg_2)
275 else:
276 raise TypeError(
277 f"Cannot parse two arguments of types 'datetime', {type(arg_2)!r}."
278 )
280 elif isinstance(arg_1, date):
281 # (date, tzinfo/str) -> fromdate @ tzinfo
282 if isinstance(arg_2, (dt_tzinfo, str)):
283 return self.type.fromdate(arg_1, tzinfo=arg_2)
284 else:
285 raise TypeError(
286 f"Cannot parse two arguments of types 'date', {type(arg_2)!r}."
287 )
289 # (str, format) -> parse @ tzinfo
290 elif isinstance(arg_1, str) and isinstance(arg_2, (str, list)):
291 dt = parser.DateTimeParser(locale).parse(
292 args[0], args[1], normalize_whitespace
293 )
294 return self.type.fromdatetime(dt, tzinfo=tz)
296 else:
297 raise TypeError(
298 f"Cannot parse two arguments of types {type(arg_1)!r} and {type(arg_2)!r}."
299 )
301 # 3+ args -> datetime-like via constructor
302 else:
303 return self.type(*args, **kwargs)
305 def utcnow(self) -> Arrow:
306 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in UTC time.
308 Usage::
310 >>> import arrow
311 >>> arrow.utcnow()
312 <Arrow [2013-05-08T05:19:07.018993+00:00]>
313 """
315 return self.type.utcnow()
317 def now(self, tz: Optional[TZ_EXPR] = None) -> Arrow:
318 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in the given
319 timezone.
321 :param tz: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to local time.
323 Usage::
325 >>> import arrow
326 >>> arrow.now()
327 <Arrow [2013-05-07T22:19:11.363410-07:00]>
329 >>> arrow.now('US/Pacific')
330 <Arrow [2013-05-07T22:19:15.251821-07:00]>
332 >>> arrow.now('+02:00')
333 <Arrow [2013-05-08T07:19:25.618646+02:00]>
335 >>> arrow.now('local')
336 <Arrow [2013-05-07T22:19:39.130059-07:00]>
337 """
339 if tz is None:
340 tz = dateutil_tz.tzlocal()
341 elif not isinstance(tz, dt_tzinfo):
342 tz = parser.TzinfoParser.parse(tz)
344 return self.type.now(tz)