xotl.tools.future.datetime
- Basic date and time types¶
This module extends the standard library’s datetime
. You may use it
as a drop-in replacement in many cases.
Avoid importing *
from this module since could be different in Python 2.7
and Python 3.3.
In Pytnon versions <= 3 date format fails for several dates, for example
date(1800, 1, 1).strftime("%Y")
. So, classes date
and
datetime
are redefined if that case.
This problem could be solved by redefining the strftime
function in the
time
module, because it is used for all strftime
methods; but (WTF),
Python double checks the year (in each method and then again in
time.strftime
function).
We added the following features.
-
xotl.tools.future.datetime.
strfdelta
(delta)[source]¶ Format a timedelta using a smart pretty algorithm.
Only two levels of values will be printed.
>>> def t(h, m): ... return timedelta(hours=h, minutes=m) >>> strfdelta(t(4, 56)) == '4h 56m' True
-
xotl.tools.future.datetime.
strftime
(dt, fmt)[source]¶ Used as
strftime
method ofdate
anddatetime
redefined classes.Also could be used with standard instances.
-
xotl.tools.future.datetime.
get_month_first
(ref=None)[source]¶ Given a reference date, returns the first date of the same month. If
ref
is not given, then uses current date as the reference.
-
xotl.tools.future.datetime.
get_month_last
(ref=None)[source]¶ Given a reference date, returns the last date of the same month. If
ref
is not given, then uses current date as the reference.
-
xotl.tools.future.datetime.
get_next_month
(ref=None, lastday=False)[source]¶ Get the first or last day of the next month.
If
lastday
is False return the first date of thenext month
. Otherwise, return the last date.The next month is computed with regards to a reference date. If
ref
is None, take the current date as the reference.Examples:
>>> get_next_month(date(2017, 1, 23)) datetime.date(2017, 2, 1)
>>> get_next_month(date(2017, 1, 23), lastday=True) datetime.date(2017, 2, 28)
New in version 1.7.3.
-
xotl.tools.future.datetime.
is_full_month
(start, end)[source]¶ Returns true if the arguments comprises a whole month.
-
xotl.tools.future.datetime.
get_previous_sunday
(ref)[source]¶ These family of functions compute the next/previous date per calendar weekday.
The argument to
ref
could be either adatetime.datetime
ordatetime.date
and the result will match the input.If
ref
is a datetime the time-related components are kept the same.Examples:
>>> d = datetime(2022, 3, 2, 19, 12) >>> get_next_monday(d) datetime.datetime(2022, 3, 7, 19, 12) >>> get_next_monday(d.date()) datetime.date(2022, 3, 7) >>> get_previous_monday(d) datetime.datetime(2022, 2, 28, 19, 12) >>> get_previous_wednesday(d.date()) datetime.date(2022, 2, 23)
-
xotl.tools.future.datetime.
daterange
([start, ]stop[, step])[source]¶ Similar to standard ‘range’ function, but for date objets.
Returns an iterator that yields each date in the range of
[start, stop)
, not including the stop.If
start
is given, it must be a date (ordatetime
) value; and in this case onlystop
may be an integer meaning the numbers of days to look ahead (or back ifstop
is negative).If only
stop
is given,start
will be the first day of stop’s month.step
, if given, should be a non-zero integer meaning the numbers of days to jump from one date to the next. It defaults to1
. If it’s positive thenstop
should happen afterstart
, otherwise no dates will be yielded. If it’s negativestop
should be beforestart
.As with
range
,stop
is never included in the yielded dates.
-
class
xotl.tools.future.datetime.
DateField
(name, nullable=False)[source]¶ A simple descriptor for dates.
Ensures that assigned values must be parseable dates and parses them.
-
class
xotl.tools.future.datetime.
TimeSpan
(start_date=None, end_date=None)[source]¶ A continuous span of time.
Time spans objects are iterable. They yield exactly two times: first the start date, and then the end date:
>>> ts = TimeSpan('2017-08-01', '2017-09-01') >>> tuple(ts) (date(2017, 8, 1), date(2017, 9, 1))
Time spans objects have two items:
>>> ts[0] date(2017, 8, 1) >>> ts[1] date(2017, 9, 1) >>> ts[:] (date(2017, 8, 1), date(2017, 9, 1))
Two time spans are equal if their start_date and end_date are equal. When comparing a time span with a date, the date is coerced to a time span (
from_date()
).Note
Comparing time spans with date time spans
coerces the time span
before comparing.A time span with its
start
set to None is unbound to the past. A time span with itsend
set to None is unbound to the future. A time span that is both unbound to the past and the future contains all possible dates. A time span that is not unbound in any direction isbound
.A bound time span is
valid
if its start date comes before its end date. Unbound time spans are always valid.Time spans can
intersect
, compared for containment of dates and by the subset/superset order operations (<=
,>=
). In this regard, they represent the set of dates betweenstart
andend
, inclusively.Warning
Time spans don’t implement the union or difference operations expected in sets because the difference/union of two span is not necessarily continuous.
-
classmethod
from_date
(date: datetime.date) → xotl.tools.future.datetime.TimeSpan[source]¶ Return a new time span that covers a single
date
.
-
past_unbound
¶ True if the time span is not bound into the past.
-
future_unbound
¶ True if the time span is not bound into the future.
-
unbound
¶ True if the time span is
unbound into the past
orunbount into the future
or both.
-
valid
¶ A bound time span is valid if it starts before it ends.
Unbound time spans are always valid.
-
__and__
(other)[source]¶ Get the time span that is the intersection with another time span.
If two time spans don’t overlap, return
EmptyTimeSpan
.If
other
is not a TimeSpan we try to create one. Ifother
is a date, we create the TimeSpan that starts and end that very day. Other types are passed unchanged to the constructor.When
other
is aDateTimeSpan
, convertself
to adate time span
before doing the intersection.
-
__lshift__
(delta)[source]¶ Return the time span displaced to the past in
delta
.Parameters: delta – The number of days to displace. It can be either an integer or a datetime.timedelta
. The integer will be converted totimedelta(days=delta)
.Note
Delta values that don’t amount to at least a day will be the same as 0.
New in version 1.8.2.
Warning
Python does have a boundaries for the dates it can represent, so displacing a TimeSpan can cause OverflowError.
-
__rshift__
(delta)[source]¶ Return the time span displaced to the future in
delta
.Parameters: delta – The number of days to displace. It can be either an integer or a datetime.timedelta
. The integer will be converted totimedelta(days=delta)
.Note
Delta values that don’t amount to at least a day will be the same as 0.
New in version 1.8.2.
Warning
Python does have a boundaries for the dates it can represent, so displacing a TimeSpan can cause OverflowError.
-
__len__
()[source]¶ The amount of dates in the span.
Warning
If the time span is
unbound
this method returns NotImplemented. This will make python complain with a TypeError.New in version 1.8.2.
-
diff
(other)[source]¶ Return the two time spans which (combined) contain all the dates in
self
which are not inother
.Notice this method returns a tuple of exactly two items.
If
other
andself
don’t overlap, return(self, EmptyTimeSpan)
.If
self <= other
is True, return the tuple with the empty time span in both positions.Otherwise
self
will have some dates which are not inother
; there are possible three cases:- other starts before or at self’s start date; return the empty time
span and the time span containing the dates after
other.end_date
up toself.end_date
- other ends at or after self’s end date; return the dates from
self.start_date
up to the date beforeother.start_date
and the empty time span. other
is fully contained inself
; return two non-empty time spans as in the previous cases.
New in version 1.9.7.
- other starts before or at self’s start date; return the empty time
span and the time span containing the dates after
-
classmethod
-
class
xotl.tools.future.datetime.
DateTimeSpan
(start_datetime=None, end_datetime=None)[source]¶ A continuous span of time (with datetime at each boundary).
DateTimeSpan
is a minor extension ofTimeSpan
, and is a subclass.DateTimeSpan objects are iterable. They yield exactly two datetimes: first the start date, and then the end date:
>>> ts = DateTimeSpan('2017-08-01 11:00', '2017-09-01 23:00') >>> tuple(ts) (datetime(2017, 8, 1, 11, 0), date(2017, 9, 1, 23, 0))
The API of DateTimeSpan is just the natural transformation of the API of
TimeSpan
.The
start_date
andend_date
attributes are interlocked with thestart_datetime
andend_datetime
. By changingstart_date
, you also changestart_datetime
with the same date at 00:00 without tzinfo. By settingstart_datetime
you also updatestart_date
. By settingend_date
you also updateend_datetime
with the same date at 23:59:59 without tzinfo.New in version 1.9.7.
Warning
DateTimeSpan is provided on a provisional basis. Future releases can change its API or remove it completely.
-
classmethod
from_datetime
(dt)[source]¶ Return a new date time span that covers a single
datetime
.If
dt
is actually a date, the start_datetime will be at ‘00:00:00’ and the end_datetime will be at ‘23:59:59’.
-
classmethod
from_timespan
(ts)[source]¶ Return a new date time span from a timespan.
Notice the start datetime will be set at ‘00:00:00’ and the end datetime at ‘23:59:59’.
If
ts
is already a DateTimeSpan, return it unchanged.
-
past_unbound
¶ True if the time span is not bound into the past.
-
future_unbound
¶ True if the time span is not bound into the future.
-
unbound
¶ True if the time span is
unbound into the past
orunbount into the future
or both.
-
valid
¶ A bound time span is valid if it starts before it ends.
Unbound time spans are always valid.
-
__contains__
(other)[source]¶ Test if datetime
other
is in the datetime span.If
other
is adate
, we convert it to a naive datetime at midnight (00:00:00).
-
__and__
(other)[source]¶ Get the date time span that is the intersection with another time span.
If two time spans don’t overlap, return the object
EmptyTimeSpan
.If
other
is not a DateTimeSpan we try to create one. Ifother
is a date/datetime, we create usefrom_datetime()
. Ifother
is TimeSpan we usefrom_timespan()
. Other types are passed unchanged to the constructor.
-
__lshift__
(delta)[source]¶ Return the date time span displaced to the past in
delta
.Parameters: delta – The number of days to displace. It can be either an integer or a datetime.timedelta
. The integer will be converted totimedelta(days=delta)
.Warning
Python does have a boundaries for the dates it can represent, so displacing can cause OverflowError.
-
__rshift__
(delta)[source]¶ Return the date time span displaced to the future in
delta
.Parameters: delta – The number of days to displace. It can be either an integer or a datetime.timedelta
. The integer will be converted totimedelta(days=delta)
.Warning
Python does have a boundaries for the dates it can represent, so displacing can cause OverflowError.
-
__len__
()¶ The amount of dates in the span.
Warning
If the time span is
unbound
this method returns NotImplemented. This will make python complain with a TypeError.New in version 1.8.2.
-
diff
(other)[source]¶ Return the two datetime spans which (combined) contain all the seconds in
self
which are not inother
.Notice this method returns a tuple of exactly two items.
If
other
andself
don’t overlap, return(self, EmptyTimeSpan)
.If
self <= other
is True, return the tuple with the empty time span in both positions.Otherwise
self
will have some datetimes which are not inother
; there are possible three cases:- other starts before or at self’s start datetime; return the empty
time span and the datetime span from the second after
other.end_datetime
up toself.end_datetime
- other ends at or after self’s end date; return the datetime span
from
self.start_datetime
up to the second beforeother.start_datetime
and the empty time span. other
is fully contained inself
; return two non-empty datetime spans as in the previous cases.
- other starts before or at self’s start datetime; return the empty
time span and the datetime span from the second after
-
classmethod
-
xotl.tools.future.datetime.
EmptyTimeSpan
¶ The empty time span. It’s not an instance of
TimeSpan
but engage set-like operations: union, intersection, etc.No date is a member of the empty time span. The empty time span is a proper subset of any time span. It’s only a superset of itself. It’s not a proper superset of any other time span nor itself.
This instance is a singleton.