Upstream myusuf3/delorean state of the touched files before 1d2926e754
This commit is contained in:
commit
e387afcdd4
2 files changed
+2020
No files matched your search
@@ -0,0 +1,774 @@
|
||||
import sys
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from functools import partial, update_wrapper
|
||||
from operator import index
|
||||
|
||||
import humanize
|
||||
from babel.dates import format_datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from tzlocal import get_localzone
|
||||
|
||||
from .exceptions import DeloreanInvalidDatetime, DeloreanInvalidTimezone
|
||||
from .timezones import timezone as get_timezone
|
||||
from .timezones import utc
|
||||
|
||||
|
||||
def get_total_second(td):
|
||||
"""
|
||||
This method takes a timedelta and return the number of seconds it
|
||||
represents with the resolution of 10**6
|
||||
"""
|
||||
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 1e6) / 1e6
|
||||
|
||||
|
||||
def is_datetime_naive(dt):
|
||||
"""
|
||||
This method returns true if the datetime is naive else returns false
|
||||
"""
|
||||
if dt.tzinfo is None:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def is_datetime_instance(dt):
|
||||
if dt is None:
|
||||
return
|
||||
if not isinstance(dt, datetime):
|
||||
raise ValueError("Please provide a datetime instance to Delorean")
|
||||
|
||||
|
||||
def _move_datetime(dt, direction, delta):
|
||||
"""
|
||||
Move datetime given delta by given direction
|
||||
"""
|
||||
if direction == "next":
|
||||
dt = dt + delta
|
||||
elif direction == "last":
|
||||
dt = dt - delta
|
||||
else:
|
||||
pass
|
||||
# raise some delorean error here
|
||||
return dt
|
||||
|
||||
|
||||
def move_datetime_day(dt, direction, num_shifts):
|
||||
delta = relativedelta(days=+num_shifts)
|
||||
return _move_datetime(dt, direction, delta)
|
||||
|
||||
|
||||
def move_datetime_namedday(dt, direction, unit):
|
||||
TOTAL_DAYS = 7
|
||||
days = {
|
||||
"monday": 1,
|
||||
"tuesday": 2,
|
||||
"wednesday": 3,
|
||||
"thursday": 4,
|
||||
"friday": 5,
|
||||
"saturday": 6,
|
||||
"sunday": 7,
|
||||
}
|
||||
|
||||
current_day = days[dt.strftime("%A").lower()]
|
||||
target_day = days[unit.lower()]
|
||||
|
||||
if direction == "next":
|
||||
if current_day < target_day:
|
||||
delta_days = target_day - current_day
|
||||
else:
|
||||
delta_days = (target_day - current_day) + TOTAL_DAYS
|
||||
elif direction == "last":
|
||||
|
||||
if current_day <= target_day:
|
||||
delta_days = (current_day - target_day) + TOTAL_DAYS
|
||||
else:
|
||||
delta_days = current_day - target_day
|
||||
|
||||
delta = relativedelta(days=+delta_days)
|
||||
return _move_datetime(dt, direction, delta)
|
||||
|
||||
|
||||
def move_datetime_month(dt, direction, num_shifts):
|
||||
"""
|
||||
Move datetime 1 month in the chosen direction.
|
||||
unit is a no-op, to keep the API the same as the day case
|
||||
"""
|
||||
delta = relativedelta(months=+num_shifts)
|
||||
return _move_datetime(dt, direction, delta)
|
||||
|
||||
|
||||
def move_datetime_week(dt, direction, num_shifts):
|
||||
"""
|
||||
Move datetime 1 week in the chosen direction.
|
||||
unit is a no-op, to keep the API the same as the day case
|
||||
"""
|
||||
delta = relativedelta(weeks=+num_shifts)
|
||||
return _move_datetime(dt, direction, delta)
|
||||
|
||||
|
||||
def move_datetime_year(dt, direction, num_shifts):
|
||||
"""
|
||||
Move datetime 1 year in the chosen direction.
|
||||
unit is a no-op, to keep the API the same as the day case
|
||||
"""
|
||||
delta = relativedelta(years=+num_shifts)
|
||||
return _move_datetime(dt, direction, delta)
|
||||
|
||||
|
||||
def move_datetime_hour(dt, direction, num_shifts):
|
||||
delta = relativedelta(hours=+num_shifts)
|
||||
return _move_datetime(dt, direction, delta)
|
||||
|
||||
|
||||
def move_datetime_minute(dt, direction, num_shifts):
|
||||
delta = relativedelta(minutes=+num_shifts)
|
||||
return _move_datetime(dt, direction, delta)
|
||||
|
||||
|
||||
def move_datetime_second(dt, direction, num_shifts):
|
||||
delta = relativedelta(seconds=+num_shifts)
|
||||
return _move_datetime(dt, direction, delta)
|
||||
|
||||
|
||||
def datetime_timezone(tz):
|
||||
"""
|
||||
This method given a timezone returns a localized datetime object.
|
||||
"""
|
||||
utc_datetime_naive = datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
# return a localized datetime to UTC
|
||||
utc_localized_datetime = localize(utc_datetime_naive, "UTC")
|
||||
# normalize the datetime to given timezone
|
||||
normalized_datetime = normalize(utc_localized_datetime, tz)
|
||||
return normalized_datetime
|
||||
|
||||
|
||||
def localize(dt, tz):
|
||||
"""
|
||||
Given a naive datetime object this method will return a localized
|
||||
datetime object
|
||||
"""
|
||||
tz = get_timezone(tz)
|
||||
|
||||
# Attaching a zone to an already-aware datetime would move the instant it
|
||||
# represents rather than describe it, so refuse rather than guess.
|
||||
if dt.tzinfo is not None:
|
||||
raise DeloreanInvalidDatetime("localize requires a naive datetime")
|
||||
|
||||
# A pytz zone from a caller still on 1.x carries no offset until localized;
|
||||
# attaching one directly would silently yield that zone's LMT offset.
|
||||
if hasattr(tz, "localize"):
|
||||
return tz.localize(dt)
|
||||
|
||||
return dt.replace(tzinfo=tz)
|
||||
|
||||
|
||||
def normalize(dt, tz):
|
||||
"""
|
||||
Given a object with a timezone return a datetime object
|
||||
normalized to the proper timezone.
|
||||
|
||||
This means take the give localized datetime and returns the
|
||||
datetime normalized to match the specified timezone.
|
||||
"""
|
||||
tz = get_timezone(tz)
|
||||
|
||||
if dt.tzinfo is None:
|
||||
raise DeloreanInvalidDatetime("normalize requires an aware datetime")
|
||||
|
||||
return dt.astimezone(tz)
|
||||
|
||||
|
||||
class Delorean(object):
|
||||
"""
|
||||
The class `Delorean <Delorean>` object. This method accepts naive
|
||||
datetime objects, with a string timezone.
|
||||
"""
|
||||
|
||||
_VALID_SHIFT_DIRECTIONS = ("last", "next")
|
||||
_VALID_SHIFT_UNITS = (
|
||||
"second",
|
||||
"minute",
|
||||
"hour",
|
||||
"day",
|
||||
"week",
|
||||
"month",
|
||||
"year",
|
||||
"monday",
|
||||
"tuesday",
|
||||
"wednesday",
|
||||
"thursday",
|
||||
"friday",
|
||||
"saturday",
|
||||
"sunday",
|
||||
)
|
||||
|
||||
def __init__(self, datetime=None, timezone=None):
|
||||
# maybe set timezone on the way in here. if here set it if not
|
||||
# use UTC
|
||||
is_datetime_instance(datetime)
|
||||
|
||||
if datetime:
|
||||
if is_datetime_naive(datetime):
|
||||
if timezone:
|
||||
self._dt = localize(datetime, timezone)
|
||||
self._tzinfo = self._dt.tzinfo
|
||||
else:
|
||||
# TODO(mlew, 2015-08-09):
|
||||
# Should we really throw an error here, or should this
|
||||
# default to UTC?)
|
||||
raise DeloreanInvalidTimezone("Provide a valid timezone")
|
||||
else:
|
||||
self._tzinfo = datetime.tzinfo
|
||||
self._dt = datetime
|
||||
else:
|
||||
if timezone:
|
||||
self._tzinfo = get_timezone(timezone)
|
||||
self._dt = datetime_timezone(self._tzinfo)
|
||||
self._tzinfo = self._dt.tzinfo
|
||||
else:
|
||||
self._tzinfo = utc
|
||||
self._dt = datetime_timezone(utc)
|
||||
|
||||
def __repr__(self):
|
||||
dt = self.datetime.replace(tzinfo=None)
|
||||
# Both zoneinfo zones and fixed offsets render as something timezone()
|
||||
# accepts, so this stays round-trippable through eval().
|
||||
return "Delorean(datetime=%r, timezone=%r)" % (dt, str(self.timezone))
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, Delorean):
|
||||
return self.epoch == other.epoch
|
||||
return False
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.epoch < other.epoch
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.epoch > other.epoch
|
||||
|
||||
def __ge__(self, other):
|
||||
return self.epoch >= other.epoch
|
||||
|
||||
def __le__(self, other):
|
||||
return self.epoch <= other.epoch
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
||||
def __add__(self, other):
|
||||
if not isinstance(other, timedelta):
|
||||
raise TypeError("Delorean objects can only be added with timedelta objects")
|
||||
dt = self._dt + other
|
||||
return Delorean(datetime=dt, timezone=self.timezone)
|
||||
|
||||
def __sub__(self, other):
|
||||
if isinstance(other, timedelta):
|
||||
dt = self._dt - other
|
||||
return Delorean(datetime=dt, timezone=self.timezone)
|
||||
elif isinstance(other, Delorean):
|
||||
return self._dt - other._dt
|
||||
else:
|
||||
raise TypeError(
|
||||
"Delorean objects can only be subtracted with timedelta or other Delorean objects"
|
||||
)
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""
|
||||
Implement __getattr__ to call `shift_date` function when function
|
||||
called does not exist
|
||||
"""
|
||||
func_parts = name.split("_")
|
||||
# is the func we are trying to call the right length?
|
||||
if len(func_parts) != 2:
|
||||
raise AttributeError
|
||||
|
||||
# is the function we are trying to call valid?
|
||||
if (
|
||||
func_parts[0] not in self._VALID_SHIFT_DIRECTIONS
|
||||
or func_parts[1] not in self._VALID_SHIFT_UNITS
|
||||
):
|
||||
raise AttributeError
|
||||
|
||||
# dispatch our function
|
||||
func = partial(self._shift_date, func_parts[0], func_parts[1])
|
||||
# update our partial with self.shift_date attributes
|
||||
update_wrapper(func, self._shift_date)
|
||||
return func
|
||||
|
||||
def _shift_date(self, direction, unit, *args):
|
||||
"""
|
||||
Shift datetime in `direction` in _VALID_SHIFT_DIRECTIONS and by some
|
||||
unit in _VALID_SHIFTS and shift that amount by some multiple,
|
||||
defined by by args[0] if it exists
|
||||
"""
|
||||
this_module = sys.modules[__name__]
|
||||
|
||||
num_shifts = 1
|
||||
if len(args) > 0:
|
||||
if unit == "second":
|
||||
num_shifts = args[0]
|
||||
else:
|
||||
try:
|
||||
num_shifts = index(args[0])
|
||||
except TypeError:
|
||||
raise TypeError(f"{unit} shifts require an integer") from None
|
||||
|
||||
if unit in [
|
||||
"monday",
|
||||
"tuesday",
|
||||
"wednesday",
|
||||
"thursday",
|
||||
"friday",
|
||||
"saturday",
|
||||
"sunday",
|
||||
]:
|
||||
shift_func = move_datetime_namedday
|
||||
dt = shift_func(self._dt, direction, unit)
|
||||
if num_shifts > 1:
|
||||
for n in range(num_shifts - 1):
|
||||
dt = shift_func(dt, direction, unit)
|
||||
else:
|
||||
shift_func = getattr(this_module, "move_datetime_%s" % unit)
|
||||
dt = shift_func(self._dt, direction, num_shifts)
|
||||
|
||||
return Delorean(datetime=dt.replace(tzinfo=None), timezone=self.timezone)
|
||||
|
||||
@property
|
||||
def timezone(self):
|
||||
"""
|
||||
Returns the tzinfo object associated with the Delorean object: a
|
||||
`zoneinfo.ZoneInfo` for a named zone, or a `datetime.timezone` for a
|
||||
fixed offset.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1), timezone='UTC')
|
||||
>>> d.timezone
|
||||
zoneinfo.ZoneInfo(key='UTC')
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
Timezones are standard library objects. Earlier versions returned
|
||||
`pytz` objects, so comparisons against `pytz.utc` and friends need
|
||||
updating to :func:`delorean.timezone` or `zoneinfo.ZoneInfo`.
|
||||
|
||||
"""
|
||||
return self._tzinfo
|
||||
|
||||
def truncate(self, s):
|
||||
"""
|
||||
Truncate the delorean object to the nearest s
|
||||
(second, minute, hour, day, month, year)
|
||||
|
||||
This is a destructive method, modifies the internal datetime
|
||||
object associated with the Delorean object.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1, 12, 10), timezone='US/Pacific')
|
||||
>>> d.truncate('hour')
|
||||
Delorean(datetime=datetime.datetime(2015, 1, 1, 12, 0), timezone='US/Pacific')
|
||||
|
||||
"""
|
||||
if s == "second":
|
||||
self._dt = self._dt.replace(microsecond=0)
|
||||
elif s == "minute":
|
||||
self._dt = self._dt.replace(second=0, microsecond=0)
|
||||
elif s == "hour":
|
||||
self._dt = self._dt.replace(minute=0, second=0, microsecond=0)
|
||||
elif s == "day":
|
||||
self._dt = self._dt.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
elif s == "month":
|
||||
self._dt = self._dt.replace(
|
||||
day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
elif s == "year":
|
||||
self._dt = self._dt.replace(
|
||||
month=1, day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
)
|
||||
else:
|
||||
raise ValueError("Invalid truncation level")
|
||||
|
||||
return self
|
||||
|
||||
@property
|
||||
def naive(self):
|
||||
"""
|
||||
Returns a naive datetime object associated with the Delorean
|
||||
object, this method simply converts the localize datetime to UTC
|
||||
and removes the tzinfo that is associated with it modifying the Delorean object.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1), timezone='US/Pacific')
|
||||
>>> d.naive
|
||||
datetime.datetime(2015, 1, 1, 8, 0)
|
||||
|
||||
"""
|
||||
self.shift("UTC")
|
||||
return self._dt.replace(tzinfo=None)
|
||||
|
||||
@classmethod
|
||||
def now(cls, timezone=None):
|
||||
if timezone:
|
||||
return cls(timezone=timezone)
|
||||
else:
|
||||
return cls(timezone=get_localzone())
|
||||
|
||||
@classmethod
|
||||
def utcnow(cls):
|
||||
return cls()
|
||||
|
||||
@property
|
||||
def midnight(self):
|
||||
"""
|
||||
Returns a new `Delorean` object for midnight of the day associated
|
||||
with this object. This object is left unchanged.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1, 12), timezone='UTC')
|
||||
>>> d.midnight
|
||||
Delorean(datetime=datetime.datetime(2015, 1, 1, 0, 0), timezone='UTC')
|
||||
|
||||
"""
|
||||
return Delorean(
|
||||
datetime=self._dt.replace(hour=0, minute=0, second=0, microsecond=0),
|
||||
timezone=self.timezone,
|
||||
)
|
||||
|
||||
@property
|
||||
def start_of_day(self):
|
||||
"""
|
||||
Returns a new `Delorean` object for the start of the day associated
|
||||
with this object. This object is left unchanged.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1, 12), timezone='UTC')
|
||||
>>> d.start_of_day
|
||||
Delorean(datetime=datetime.datetime(2015, 1, 1, 0, 0), timezone='UTC')
|
||||
|
||||
"""
|
||||
return self.midnight
|
||||
|
||||
@property
|
||||
def end_of_day(self):
|
||||
"""
|
||||
Returns a new `Delorean` object for the end of the day associated
|
||||
with this object. This object is left unchanged.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1, 12), timezone='UTC')
|
||||
>>> d.end_of_day
|
||||
Delorean(datetime=datetime.datetime(2015, 1, 1, 23, 59, 59, 999999), timezone='UTC')
|
||||
|
||||
"""
|
||||
return Delorean(
|
||||
datetime=self._dt.replace(
|
||||
hour=23, minute=59, second=59, microsecond=999999
|
||||
),
|
||||
timezone=self.timezone,
|
||||
)
|
||||
|
||||
@property
|
||||
def start_of_month(self):
|
||||
"""
|
||||
Returns a new `Delorean` object for the first moment of the month
|
||||
associated with this object. This object is left unchanged.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 5, 15, 14, 30), timezone='UTC')
|
||||
>>> d.start_of_month
|
||||
Delorean(datetime=datetime.datetime(2015, 5, 1, 0, 0), timezone='UTC')
|
||||
|
||||
"""
|
||||
return Delorean(
|
||||
datetime=self._dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0),
|
||||
timezone=self.timezone,
|
||||
)
|
||||
|
||||
@property
|
||||
def end_of_month(self):
|
||||
"""
|
||||
Returns a new `Delorean` object for the last moment of the month
|
||||
associated with this object, accounting for month length and leap
|
||||
years. This object is left unchanged.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 2, 15, 14, 30), timezone='UTC')
|
||||
>>> d.end_of_month
|
||||
Delorean(datetime=datetime.datetime(2015, 2, 28, 23, 59, 59, 999999), timezone='UTC')
|
||||
|
||||
"""
|
||||
end = self._dt.replace(
|
||||
hour=23, minute=59, second=59, microsecond=999999
|
||||
) + relativedelta(day=31)
|
||||
return Delorean(datetime=end, timezone=self.timezone)
|
||||
|
||||
@property
|
||||
def start_of_year(self):
|
||||
"""
|
||||
Returns a new `Delorean` object for the first moment of the year
|
||||
associated with this object. This object is left unchanged.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 5, 15, 14, 30), timezone='UTC')
|
||||
>>> d.start_of_year
|
||||
Delorean(datetime=datetime.datetime(2015, 1, 1, 0, 0), timezone='UTC')
|
||||
|
||||
"""
|
||||
return Delorean(
|
||||
datetime=self._dt.replace(
|
||||
month=1, day=1, hour=0, minute=0, second=0, microsecond=0
|
||||
),
|
||||
timezone=self.timezone,
|
||||
)
|
||||
|
||||
@property
|
||||
def end_of_year(self):
|
||||
"""
|
||||
Returns a new `Delorean` object for the last moment of the year
|
||||
associated with this object. This object is left unchanged.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 5, 15, 14, 30), timezone='UTC')
|
||||
>>> d.end_of_year
|
||||
Delorean(datetime=datetime.datetime(2015, 12, 31, 23, 59, 59, 999999), timezone='UTC')
|
||||
|
||||
"""
|
||||
return Delorean(
|
||||
datetime=self._dt.replace(
|
||||
month=12, day=31, hour=23, minute=59, second=59, microsecond=999999
|
||||
),
|
||||
timezone=self.timezone,
|
||||
)
|
||||
|
||||
def shift(self, timezone):
|
||||
"""
|
||||
Shifts the timezone from the current timezone to the specified timezone associated with the Delorean object,
|
||||
modifying the Delorean object and returning the modified object.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1), timezone='US/Pacific')
|
||||
>>> d.shift('UTC')
|
||||
Delorean(datetime=datetime.datetime(2015, 1, 1, 8, 0), timezone='UTC')
|
||||
|
||||
"""
|
||||
try:
|
||||
self._tzinfo = get_timezone(timezone)
|
||||
except DeloreanInvalidTimezone:
|
||||
raise DeloreanInvalidTimezone("Provide a valid timezone") from None
|
||||
self._dt = self._dt.astimezone(self._tzinfo)
|
||||
self._tzinfo = self._dt.tzinfo
|
||||
return self
|
||||
|
||||
@property
|
||||
def timestamp(self):
|
||||
"""
|
||||
Returns the total seconds since the Unix epoch associated with
|
||||
the Delorean object.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1), timezone='US/Pacific')
|
||||
>>> d.timestamp
|
||||
1420099200.0
|
||||
|
||||
"""
|
||||
epoch_sec = datetime.fromtimestamp(0, timezone.utc)
|
||||
now_sec = self._dt.astimezone(utc)
|
||||
delta_sec = now_sec - epoch_sec
|
||||
return get_total_second(delta_sec)
|
||||
|
||||
@property
|
||||
def epoch(self):
|
||||
"""
|
||||
Alias of :attr:`timestamp`, kept for backwards compatibility.
|
||||
|
||||
The value is seconds since the Unix epoch, so `timestamp` is the
|
||||
more accurate name; the epoch itself is the fixed point the count
|
||||
starts from.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1), timezone='US/Pacific')
|
||||
>>> d.epoch
|
||||
1420099200.0
|
||||
|
||||
"""
|
||||
return self.timestamp
|
||||
|
||||
@property
|
||||
def date(self):
|
||||
"""
|
||||
Returns the actual date object associated with
|
||||
the Delorean object.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1, 12, 15), timezone='US/Pacific')
|
||||
>>> d.date
|
||||
datetime.date(2015, 1, 1)
|
||||
|
||||
"""
|
||||
return self._dt.date()
|
||||
|
||||
@property
|
||||
def datetime(self):
|
||||
"""
|
||||
Returns the actual datetime object associated with
|
||||
the Delorean object.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1, 12, 15), timezone='UTC')
|
||||
>>> d.datetime
|
||||
datetime.datetime(2015, 1, 1, 12, 15, tzinfo=zoneinfo.ZoneInfo(key='UTC'))
|
||||
"""
|
||||
return self._dt
|
||||
|
||||
def replace(self, **kwargs):
|
||||
"""
|
||||
Returns a new Delorean object after applying replace on the
|
||||
existing datetime object.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import datetime
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1, 12, 15), timezone='UTC')
|
||||
>>> d.replace(hour=8)
|
||||
Delorean(datetime=datetime.datetime(2015, 1, 1, 8, 15), timezone='UTC')
|
||||
"""
|
||||
|
||||
return Delorean(datetime=self._dt.replace(**kwargs), timezone=self.timezone)
|
||||
|
||||
def humanize(self):
|
||||
"""
|
||||
Humanize relative to now:
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from datetime import timedelta
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> past = Delorean.utcnow() - timedelta(hours=1)
|
||||
>>> past.humanize()
|
||||
'an hour ago'
|
||||
|
||||
"""
|
||||
now = self.now(self.timezone)
|
||||
|
||||
return humanize.naturaltime(now - self)
|
||||
|
||||
def format_datetime(self, format="medium", locale="en_US"):
|
||||
r"""
|
||||
Return a date string formatted to the given pattern.
|
||||
|
||||
Note that CLDR separates the time from the AM/PM marker with a narrow
|
||||
no-break space (``\u202f``), not a plain space.
|
||||
|
||||
.. testsetup::
|
||||
|
||||
from delorean import Delorean
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> d = Delorean(datetime(2015, 1, 1, 12, 30), timezone='US/Pacific')
|
||||
>>> d.format_datetime(locale='en_US')
|
||||
'Jan 1, 2015, 12:30:00\u202fPM'
|
||||
|
||||
>>> d.format_datetime(format='long', locale='de_DE')
|
||||
'1. Januar 2015, 12:30:00 -0800'
|
||||
|
||||
:param format: one of "full", "long", "medium", "short", or a custom datetime pattern
|
||||
:param locale: a locale identifier
|
||||
|
||||
"""
|
||||
return format_datetime(self._dt, format=format, locale=locale)
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user