Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/arrow/factory.py: 29%
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:
42 ... # pragma: no cover
44 @overload
45 def get(
46 self,
47 __obj: Union[
48 Arrow,
49 datetime,
50 date,
51 struct_time,
52 dt_tzinfo,
53 int,
54 float,
55 str,
56 Tuple[int, int, int],
57 ],
58 *,
59 locale: str = DEFAULT_LOCALE,
60 tzinfo: Optional[TZ_EXPR] = None,
61 normalize_whitespace: bool = False,
62 ) -> Arrow:
63 ... # pragma: no cover
65 @overload
66 def get(
67 self,
68 __arg1: Union[datetime, date],
69 __arg2: TZ_EXPR,
70 *,
71 locale: str = DEFAULT_LOCALE,
72 tzinfo: Optional[TZ_EXPR] = None,
73 normalize_whitespace: bool = False,
74 ) -> Arrow:
75 ... # pragma: no cover
77 @overload
78 def get(
79 self,
80 __arg1: str,
81 __arg2: Union[str, List[str]],
82 *,
83 locale: str = DEFAULT_LOCALE,
84 tzinfo: Optional[TZ_EXPR] = None,
85 normalize_whitespace: bool = False,
86 ) -> Arrow:
87 ... # pragma: no cover
89 def get(self, *args: Any, **kwargs: Any) -> Arrow:
90 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object based on flexible inputs.
92 :param locale: (optional) a ``str`` specifying a locale for the parser. Defaults to 'en-us'.
93 :param tzinfo: (optional) a :ref:`timezone expression <tz-expr>` or tzinfo object.
94 Replaces the timezone unless using an input form that is explicitly UTC or specifies
95 the timezone in a positional argument. Defaults to UTC.
96 :param normalize_whitespace: (optional) a ``bool`` specifying whether or not to normalize
97 redundant whitespace (spaces, tabs, and newlines) in a datetime string before parsing.
98 Defaults to false.
100 Usage::
102 >>> import arrow
104 **No inputs** to get current UTC time::
106 >>> arrow.get()
107 <Arrow [2013-05-08T05:51:43.316458+00:00]>
109 **One** :class:`Arrow <arrow.arrow.Arrow>` object, to get a copy.
111 >>> arw = arrow.utcnow()
112 >>> arrow.get(arw)
113 <Arrow [2013-10-23T15:21:54.354846+00:00]>
115 **One** ``float`` or ``int``, convertible to a floating-point timestamp, to get
116 that timestamp in UTC::
118 >>> arrow.get(1367992474.293378)
119 <Arrow [2013-05-08T05:54:34.293378+00:00]>
121 >>> arrow.get(1367992474)
122 <Arrow [2013-05-08T05:54:34+00:00]>
124 **One** ISO 8601-formatted ``str``, to parse it::
126 >>> arrow.get('2013-09-29T01:26:43.830580')
127 <Arrow [2013-09-29T01:26:43.830580+00:00]>
129 **One** ISO 8601-formatted ``str``, in basic format, to parse it::
131 >>> arrow.get('20160413T133656.456289')
132 <Arrow [2016-04-13T13:36:56.456289+00:00]>
134 **One** ``tzinfo``, to get the current time **converted** to that timezone::
136 >>> arrow.get(tz.tzlocal())
137 <Arrow [2013-05-07T22:57:28.484717-07:00]>
139 **One** naive ``datetime``, to get that datetime in UTC::
141 >>> arrow.get(datetime(2013, 5, 5))
142 <Arrow [2013-05-05T00:00:00+00:00]>
144 **One** aware ``datetime``, to get that datetime::
146 >>> arrow.get(datetime(2013, 5, 5, tzinfo=tz.tzlocal()))
147 <Arrow [2013-05-05T00:00:00-07:00]>
149 **One** naive ``date``, to get that date in UTC::
151 >>> arrow.get(date(2013, 5, 5))
152 <Arrow [2013-05-05T00:00:00+00:00]>
154 **One** time.struct time::
156 >>> arrow.get(gmtime(0))
157 <Arrow [1970-01-01T00:00:00+00:00]>
159 **One** iso calendar ``tuple``, to get that week date in UTC::
161 >>> arrow.get((2013, 18, 7))
162 <Arrow [2013-05-05T00:00:00+00:00]>
164 **Two** arguments, a naive or aware ``datetime``, and a replacement
165 :ref:`timezone expression <tz-expr>`::
167 >>> arrow.get(datetime(2013, 5, 5), 'US/Pacific')
168 <Arrow [2013-05-05T00:00:00-07:00]>
170 **Two** arguments, a naive ``date``, and a replacement
171 :ref:`timezone expression <tz-expr>`::
173 >>> arrow.get(date(2013, 5, 5), 'US/Pacific')
174 <Arrow [2013-05-05T00:00:00-07:00]>
176 **Two** arguments, both ``str``, to parse the first according to the format of the second::
178 >>> arrow.get('2013-05-05 12:30:45 America/Chicago', 'YYYY-MM-DD HH:mm:ss ZZZ')
179 <Arrow [2013-05-05T12:30:45-05:00]>
181 **Two** arguments, first a ``str`` to parse and second a ``list`` of formats to try::
183 >>> arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'YYYY-MM-DD HH:mm:ss'])
184 <Arrow [2013-05-05T12:30:45+00:00]>
186 **Three or more** arguments, as for the direct constructor of an ``Arrow`` object::
188 >>> arrow.get(2013, 5, 5, 12, 30, 45)
189 <Arrow [2013-05-05T12:30:45+00:00]>
191 """
193 arg_count = len(args)
194 locale = kwargs.pop("locale", DEFAULT_LOCALE)
195 tz = kwargs.get("tzinfo", None)
196 normalize_whitespace = kwargs.pop("normalize_whitespace", False)
198 # if kwargs given, send to constructor unless only tzinfo provided
199 if len(kwargs) > 1:
200 arg_count = 3
202 # tzinfo kwarg is not provided
203 if len(kwargs) == 1 and tz is None:
204 arg_count = 3
206 # () -> now, @ tzinfo or utc
207 if arg_count == 0:
208 if isinstance(tz, str):
209 tz = parser.TzinfoParser.parse(tz)
210 return self.type.now(tzinfo=tz)
212 if isinstance(tz, dt_tzinfo):
213 return self.type.now(tzinfo=tz)
215 return self.type.utcnow()
217 if arg_count == 1:
218 arg = args[0]
219 if isinstance(arg, Decimal):
220 arg = float(arg)
222 # (None) -> raises an exception
223 if arg is None:
224 raise TypeError("Cannot parse argument of type None.")
226 # try (int, float) -> from timestamp @ tzinfo
227 elif not isinstance(arg, str) and is_timestamp(arg):
228 if tz is None:
229 # set to UTC by default
230 tz = timezone.utc
231 return self.type.fromtimestamp(arg, tzinfo=tz)
233 # (Arrow) -> from the object's datetime @ tzinfo
234 elif isinstance(arg, Arrow):
235 return self.type.fromdatetime(arg.datetime, tzinfo=tz)
237 # (datetime) -> from datetime @ tzinfo
238 elif isinstance(arg, datetime):
239 return self.type.fromdatetime(arg, tzinfo=tz)
241 # (date) -> from date @ tzinfo
242 elif isinstance(arg, date):
243 return self.type.fromdate(arg, tzinfo=tz)
245 # (tzinfo) -> now @ tzinfo
246 elif isinstance(arg, dt_tzinfo):
247 return self.type.now(tzinfo=arg)
249 # (str) -> parse @ tzinfo
250 elif isinstance(arg, str):
251 dt = parser.DateTimeParser(locale).parse_iso(arg, normalize_whitespace)
252 return self.type.fromdatetime(dt, tzinfo=tz)
254 # (struct_time) -> from struct_time
255 elif isinstance(arg, struct_time):
256 return self.type.utcfromtimestamp(calendar.timegm(arg))
258 # (iso calendar) -> convert then from date @ tzinfo
259 elif isinstance(arg, tuple) and len(arg) == 3:
260 d = iso_to_gregorian(*arg)
261 return self.type.fromdate(d, tzinfo=tz)
263 else:
264 raise TypeError(f"Cannot parse single argument of type {type(arg)!r}.")
266 elif arg_count == 2:
267 arg_1, arg_2 = args[0], args[1]
269 if isinstance(arg_1, datetime):
270 # (datetime, tzinfo/str) -> fromdatetime @ tzinfo
271 if isinstance(arg_2, (dt_tzinfo, str)):
272 return self.type.fromdatetime(arg_1, tzinfo=arg_2)
273 else:
274 raise TypeError(
275 f"Cannot parse two arguments of types 'datetime', {type(arg_2)!r}."
276 )
278 elif isinstance(arg_1, date):
279 # (date, tzinfo/str) -> fromdate @ tzinfo
280 if isinstance(arg_2, (dt_tzinfo, str)):
281 return self.type.fromdate(arg_1, tzinfo=arg_2)
282 else:
283 raise TypeError(
284 f"Cannot parse two arguments of types 'date', {type(arg_2)!r}."
285 )
287 # (str, format) -> parse @ tzinfo
288 elif isinstance(arg_1, str) and isinstance(arg_2, (str, list)):
289 dt = parser.DateTimeParser(locale).parse(
290 args[0], args[1], normalize_whitespace
291 )
292 return self.type.fromdatetime(dt, tzinfo=tz)
294 else:
295 raise TypeError(
296 f"Cannot parse two arguments of types {type(arg_1)!r} and {type(arg_2)!r}."
297 )
299 # 3+ args -> datetime-like via constructor
300 else:
301 return self.type(*args, **kwargs)
303 def utcnow(self) -> Arrow:
304 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in UTC time.
306 Usage::
308 >>> import arrow
309 >>> arrow.utcnow()
310 <Arrow [2013-05-08T05:19:07.018993+00:00]>
311 """
313 return self.type.utcnow()
315 def now(self, tz: Optional[TZ_EXPR] = None) -> Arrow:
316 """Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in the given
317 timezone.
319 :param tz: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to local time.
321 Usage::
323 >>> import arrow
324 >>> arrow.now()
325 <Arrow [2013-05-07T22:19:11.363410-07:00]>
327 >>> arrow.now('US/Pacific')
328 <Arrow [2013-05-07T22:19:15.251821-07:00]>
330 >>> arrow.now('+02:00')
331 <Arrow [2013-05-08T07:19:25.618646+02:00]>
333 >>> arrow.now('local')
334 <Arrow [2013-05-07T22:19:39.130059-07:00]>
335 """
337 if tz is None:
338 tz = datetime.now().astimezone().tzinfo
339 elif not isinstance(tz, dt_tzinfo):
340 tz = parser.TzinfoParser.parse(tz)
342 return self.type.now(tz)