Spaces:
Runtime error
Runtime error
""" | |
Implements the :class:`ArrowFactory <arrow.factory.ArrowFactory>` class, | |
providing factory methods for common :class:`Arrow <arrow.arrow.Arrow>` | |
construction scenarios. | |
""" | |
import calendar | |
from datetime import date, datetime | |
from datetime import tzinfo as dt_tzinfo | |
from decimal import Decimal | |
from time import struct_time | |
from typing import Any, List, Optional, Tuple, Type, Union, overload | |
from dateutil import tz as dateutil_tz | |
from arrow import parser | |
from arrow.arrow import TZ_EXPR, Arrow | |
from arrow.constants import DEFAULT_LOCALE | |
from arrow.util import is_timestamp, iso_to_gregorian | |
class ArrowFactory: | |
"""A factory for generating :class:`Arrow <arrow.arrow.Arrow>` objects. | |
:param type: (optional) the :class:`Arrow <arrow.arrow.Arrow>`-based class to construct from. | |
Defaults to :class:`Arrow <arrow.arrow.Arrow>`. | |
""" | |
type: Type[Arrow] | |
def __init__(self, type: Type[Arrow] = Arrow) -> None: | |
self.type = type | |
def get( | |
self, | |
*, | |
locale: str = DEFAULT_LOCALE, | |
tzinfo: Optional[TZ_EXPR] = None, | |
normalize_whitespace: bool = False, | |
) -> Arrow: | |
... # pragma: no cover | |
def get( | |
self, | |
__obj: Union[ | |
Arrow, | |
datetime, | |
date, | |
struct_time, | |
dt_tzinfo, | |
int, | |
float, | |
str, | |
Tuple[int, int, int], | |
], | |
*, | |
locale: str = DEFAULT_LOCALE, | |
tzinfo: Optional[TZ_EXPR] = None, | |
normalize_whitespace: bool = False, | |
) -> Arrow: | |
... # pragma: no cover | |
def get( | |
self, | |
__arg1: Union[datetime, date], | |
__arg2: TZ_EXPR, | |
*, | |
locale: str = DEFAULT_LOCALE, | |
tzinfo: Optional[TZ_EXPR] = None, | |
normalize_whitespace: bool = False, | |
) -> Arrow: | |
... # pragma: no cover | |
def get( | |
self, | |
__arg1: str, | |
__arg2: Union[str, List[str]], | |
*, | |
locale: str = DEFAULT_LOCALE, | |
tzinfo: Optional[TZ_EXPR] = None, | |
normalize_whitespace: bool = False, | |
) -> Arrow: | |
... # pragma: no cover | |
def get(self, *args: Any, **kwargs: Any) -> Arrow: | |
"""Returns an :class:`Arrow <arrow.arrow.Arrow>` object based on flexible inputs. | |
:param locale: (optional) a ``str`` specifying a locale for the parser. Defaults to 'en-us'. | |
:param tzinfo: (optional) a :ref:`timezone expression <tz-expr>` or tzinfo object. | |
Replaces the timezone unless using an input form that is explicitly UTC or specifies | |
the timezone in a positional argument. Defaults to UTC. | |
:param normalize_whitespace: (optional) a ``bool`` specifying whether or not to normalize | |
redundant whitespace (spaces, tabs, and newlines) in a datetime string before parsing. | |
Defaults to false. | |
Usage:: | |
>>> import arrow | |
**No inputs** to get current UTC time:: | |
>>> arrow.get() | |
<Arrow [2013-05-08T05:51:43.316458+00:00]> | |
**One** :class:`Arrow <arrow.arrow.Arrow>` object, to get a copy. | |
>>> arw = arrow.utcnow() | |
>>> arrow.get(arw) | |
<Arrow [2013-10-23T15:21:54.354846+00:00]> | |
**One** ``float`` or ``int``, convertible to a floating-point timestamp, to get | |
that timestamp in UTC:: | |
>>> arrow.get(1367992474.293378) | |
<Arrow [2013-05-08T05:54:34.293378+00:00]> | |
>>> arrow.get(1367992474) | |
<Arrow [2013-05-08T05:54:34+00:00]> | |
**One** ISO 8601-formatted ``str``, to parse it:: | |
>>> arrow.get('2013-09-29T01:26:43.830580') | |
<Arrow [2013-09-29T01:26:43.830580+00:00]> | |
**One** ISO 8601-formatted ``str``, in basic format, to parse it:: | |
>>> arrow.get('20160413T133656.456289') | |
<Arrow [2016-04-13T13:36:56.456289+00:00]> | |
**One** ``tzinfo``, to get the current time **converted** to that timezone:: | |
>>> arrow.get(tz.tzlocal()) | |
<Arrow [2013-05-07T22:57:28.484717-07:00]> | |
**One** naive ``datetime``, to get that datetime in UTC:: | |
>>> arrow.get(datetime(2013, 5, 5)) | |
<Arrow [2013-05-05T00:00:00+00:00]> | |
**One** aware ``datetime``, to get that datetime:: | |
>>> arrow.get(datetime(2013, 5, 5, tzinfo=tz.tzlocal())) | |
<Arrow [2013-05-05T00:00:00-07:00]> | |
**One** naive ``date``, to get that date in UTC:: | |
>>> arrow.get(date(2013, 5, 5)) | |
<Arrow [2013-05-05T00:00:00+00:00]> | |
**One** time.struct time:: | |
>>> arrow.get(gmtime(0)) | |
<Arrow [1970-01-01T00:00:00+00:00]> | |
**One** iso calendar ``tuple``, to get that week date in UTC:: | |
>>> arrow.get((2013, 18, 7)) | |
<Arrow [2013-05-05T00:00:00+00:00]> | |
**Two** arguments, a naive or aware ``datetime``, and a replacement | |
:ref:`timezone expression <tz-expr>`:: | |
>>> arrow.get(datetime(2013, 5, 5), 'US/Pacific') | |
<Arrow [2013-05-05T00:00:00-07:00]> | |
**Two** arguments, a naive ``date``, and a replacement | |
:ref:`timezone expression <tz-expr>`:: | |
>>> arrow.get(date(2013, 5, 5), 'US/Pacific') | |
<Arrow [2013-05-05T00:00:00-07:00]> | |
**Two** arguments, both ``str``, to parse the first according to the format of the second:: | |
>>> arrow.get('2013-05-05 12:30:45 America/Chicago', 'YYYY-MM-DD HH:mm:ss ZZZ') | |
<Arrow [2013-05-05T12:30:45-05:00]> | |
**Two** arguments, first a ``str`` to parse and second a ``list`` of formats to try:: | |
>>> arrow.get('2013-05-05 12:30:45', ['MM/DD/YYYY', 'YYYY-MM-DD HH:mm:ss']) | |
<Arrow [2013-05-05T12:30:45+00:00]> | |
**Three or more** arguments, as for the direct constructor of an ``Arrow`` object:: | |
>>> arrow.get(2013, 5, 5, 12, 30, 45) | |
<Arrow [2013-05-05T12:30:45+00:00]> | |
""" | |
arg_count = len(args) | |
locale = kwargs.pop("locale", DEFAULT_LOCALE) | |
tz = kwargs.get("tzinfo", None) | |
normalize_whitespace = kwargs.pop("normalize_whitespace", False) | |
# if kwargs given, send to constructor unless only tzinfo provided | |
if len(kwargs) > 1: | |
arg_count = 3 | |
# tzinfo kwarg is not provided | |
if len(kwargs) == 1 and tz is None: | |
arg_count = 3 | |
# () -> now, @ tzinfo or utc | |
if arg_count == 0: | |
if isinstance(tz, str): | |
tz = parser.TzinfoParser.parse(tz) | |
return self.type.now(tzinfo=tz) | |
if isinstance(tz, dt_tzinfo): | |
return self.type.now(tzinfo=tz) | |
return self.type.utcnow() | |
if arg_count == 1: | |
arg = args[0] | |
if isinstance(arg, Decimal): | |
arg = float(arg) | |
# (None) -> raises an exception | |
if arg is None: | |
raise TypeError("Cannot parse argument of type None.") | |
# try (int, float) -> from timestamp @ tzinfo | |
elif not isinstance(arg, str) and is_timestamp(arg): | |
if tz is None: | |
# set to UTC by default | |
tz = dateutil_tz.tzutc() | |
return self.type.fromtimestamp(arg, tzinfo=tz) | |
# (Arrow) -> from the object's datetime @ tzinfo | |
elif isinstance(arg, Arrow): | |
return self.type.fromdatetime(arg.datetime, tzinfo=tz) | |
# (datetime) -> from datetime @ tzinfo | |
elif isinstance(arg, datetime): | |
return self.type.fromdatetime(arg, tzinfo=tz) | |
# (date) -> from date @ tzinfo | |
elif isinstance(arg, date): | |
return self.type.fromdate(arg, tzinfo=tz) | |
# (tzinfo) -> now @ tzinfo | |
elif isinstance(arg, dt_tzinfo): | |
return self.type.now(tzinfo=arg) | |
# (str) -> parse @ tzinfo | |
elif isinstance(arg, str): | |
dt = parser.DateTimeParser(locale).parse_iso(arg, normalize_whitespace) | |
return self.type.fromdatetime(dt, tzinfo=tz) | |
# (struct_time) -> from struct_time | |
elif isinstance(arg, struct_time): | |
return self.type.utcfromtimestamp(calendar.timegm(arg)) | |
# (iso calendar) -> convert then from date @ tzinfo | |
elif isinstance(arg, tuple) and len(arg) == 3: | |
d = iso_to_gregorian(*arg) | |
return self.type.fromdate(d, tzinfo=tz) | |
else: | |
raise TypeError(f"Cannot parse single argument of type {type(arg)!r}.") | |
elif arg_count == 2: | |
arg_1, arg_2 = args[0], args[1] | |
if isinstance(arg_1, datetime): | |
# (datetime, tzinfo/str) -> fromdatetime @ tzinfo | |
if isinstance(arg_2, (dt_tzinfo, str)): | |
return self.type.fromdatetime(arg_1, tzinfo=arg_2) | |
else: | |
raise TypeError( | |
f"Cannot parse two arguments of types 'datetime', {type(arg_2)!r}." | |
) | |
elif isinstance(arg_1, date): | |
# (date, tzinfo/str) -> fromdate @ tzinfo | |
if isinstance(arg_2, (dt_tzinfo, str)): | |
return self.type.fromdate(arg_1, tzinfo=arg_2) | |
else: | |
raise TypeError( | |
f"Cannot parse two arguments of types 'date', {type(arg_2)!r}." | |
) | |
# (str, format) -> parse @ tzinfo | |
elif isinstance(arg_1, str) and isinstance(arg_2, (str, list)): | |
dt = parser.DateTimeParser(locale).parse( | |
args[0], args[1], normalize_whitespace | |
) | |
return self.type.fromdatetime(dt, tzinfo=tz) | |
else: | |
raise TypeError( | |
f"Cannot parse two arguments of types {type(arg_1)!r} and {type(arg_2)!r}." | |
) | |
# 3+ args -> datetime-like via constructor | |
else: | |
return self.type(*args, **kwargs) | |
def utcnow(self) -> Arrow: | |
"""Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in UTC time. | |
Usage:: | |
>>> import arrow | |
>>> arrow.utcnow() | |
<Arrow [2013-05-08T05:19:07.018993+00:00]> | |
""" | |
return self.type.utcnow() | |
def now(self, tz: Optional[TZ_EXPR] = None) -> Arrow: | |
"""Returns an :class:`Arrow <arrow.arrow.Arrow>` object, representing "now" in the given | |
timezone. | |
:param tz: (optional) A :ref:`timezone expression <tz-expr>`. Defaults to local time. | |
Usage:: | |
>>> import arrow | |
>>> arrow.now() | |
<Arrow [2013-05-07T22:19:11.363410-07:00]> | |
>>> arrow.now('US/Pacific') | |
<Arrow [2013-05-07T22:19:15.251821-07:00]> | |
>>> arrow.now('+02:00') | |
<Arrow [2013-05-08T07:19:25.618646+02:00]> | |
>>> arrow.now('local') | |
<Arrow [2013-05-07T22:19:39.130059-07:00]> | |
""" | |
if tz is None: | |
tz = dateutil_tz.tzlocal() | |
elif not isinstance(tz, dt_tzinfo): | |
tz = parser.TzinfoParser.parse(tz) | |
return self.type.now(tz) | |