src.datelabel module

Classes and utility methods for dealing with dates as expressed in filenames and paths. Intended use case is, eg, determining if a file contains data for a given year from the filename, without having to open it and parse the header.

Note

These classes should not be used for calendar math! We currently implement and test comparison logic only, not anything more (eg addition, subtraction).

Note

These classes are based on the datetime standard library, and as such assume a proleptic Gregorian calendar for all dates.

Note

Timezone support is not currently implemented.

class src.datelabel.AtomicInterval(left, lower, upper, right)[source]

Bases: object

This class represents an atomic interval. An atomic interval is a single interval, with a lower and upper bounds, and two (closed or open) boundaries.

CLOSED = True
OPEN = False
__init__(left, lower, upper, right)[source]

Create an atomic interval. If a bound is set to infinity (regardless of its sign), the corresponding boundary will be exclusive.

Parameters
  • left – Boolean indicating if left boundary is inclusive (True) or exclusive (False).

  • lower – value of the lower bound.

  • upper – value of the upper bound.

  • right – Boolean indicating if right boundary is inclusive (True) or exclusive (False).

_left
_lower
_upper
_right
property left

Boolean indicating whether the left boundary is inclusive (True) or exclusive (False).

property lower

Lower bound value.

property upper

Upper bound value.

property right

Boolean indicating whether the right boundary is inclusive (True) or exclusive (False).

is_empty()[source]

Test interval emptiness. :return: True if interval is empty, False otherwise.

replace(left=None, lower=None, upper=None, right=None, ignore_inf=True)[source]

Create a new interval based on the current one and the provided values. Callable can be passed instead of values. In that case, it is called with the current corresponding value except if ignore_inf if set (default) and the corresponding bound is an infinity.

Parameters
  • left – (a function of) left boundary.

  • lower – (a function of) value of the lower bound.

  • upper – (a function of) value of the upper bound.

  • right – (a function of) right boundary.

  • ignore_inf – ignore infinities if functions are provided (default is True).

Returns: an Interval instance

overlaps(other, adjacent=False)[source]

Test if intervals have any overlapping value. If ‘adjacent’ is set to True (default is False), then it returns True for adjacent intervals as well (e.g., [1, 2) and [2, 3], but not [1, 2) and (2, 3]). :param other: an atomic interval. :param adjacent: set to True to accept adjacent intervals as well. :return: True if intervals overlap, False otherwise.

intersection(other)[source]

Return the intersection of two intervals. :param other: an interval. :return: the intersection of the intervals.

union(other)[source]

Return the union of two intervals. If the union cannot be represented using a single atomic interval, return an Interval instance (which corresponds to an union of atomic intervals). :param other: an interval. :return: the union of the intervals.

contains(item)[source]

Test if given item is contained in this interval. This method accepts atomic intervals, intervals and arbitrary values. :param item: an atomic interval, an interval or any arbitrary value. :return: True if given item is contained, False otherwise.

adjoins_left(other)[source]
adjoins_right(other)[source]
adjoins(other)[source]
classmethod span(*args)[source]
classmethod contiguous_span(*args)[source]
class src.datelabel._DateMixin[source]

Bases: object

Utility methods for dealing with dates.

static date_format(dt, precision=None)[source]

Print date in YYYYMMDDHHMMSS format, with length being set automatically from precision.

Note

strftime() is broken for dates prior to 1900 in python < 3.3, see https://bugs.python.org/issue1777412 and https://stackoverflow.com/q/10263956. For this reason, the workaround implemented here should be used instead.

classmethod increment(dt, precision)[source]

Return a copy of dt advanced by one time unit as specified by the precision attribute.

classmethod decrement(dt, precision)[source]

Return a copy of Date moved back by one time unit as specified by the precision attribute.

static _inc_dec_common(dt, precision, delta)[source]
class src.datelabel.DateRange(start, end=None, precision=None)[source]

Bases: src.datelabel.AtomicInterval, src.datelabel._DateMixin

Class representing a range of variable-precision dates.

Note

This is defined as a closed interval (containing both endpoints). Eg, DateRange(‘1990-1999’) starts at 0:00 on 1 Jan 1990 and ends at 23:59 on 31 Dec 1999.

_range_sep = '-'
__init__(start, end=None, precision=None)[source]

Init method for DateRange.

_left
_lower
_upper
_right
static _warning_minmax(*args)[source]
static _coerce_to_datetime(dt, is_lower)[source]
classmethod _coerce_to_self(item)[source]
property start
property end
classmethod from_contiguous_span(*args)[source]
classmethod from_date_span(*args)[source]
format(precision=None)[source]
overlaps(item)[source]

Test if intervals have any overlapping value. If ‘adjacent’ is set to True (default is False), then it returns True for adjacent intervals as well (e.g., [1, 2) and [2, 3], but not [1, 2) and (2, 3]). :param other: an atomic interval. :param adjacent: set to True to accept adjacent intervals as well. :return: True if intervals overlap, False otherwise.

contains(item)[source]

Test if given item is contained in this interval. This method accepts atomic intervals, intervals and arbitrary values. :param item: an atomic interval, an interval or any arbitrary value. :return: True if given item is contained, False otherwise.

intersection(item, precision=None)[source]

Return the intersection of two intervals. :param other: an interval. :return: the intersection of the intervals.

class src.datelabel.Date(*args, **kwargs)[source]

Bases: src.datelabel.DateRange

Define a date with variable level precision.

Note

Date objects are mapped to datetimes representing the start of the interval implied by their precision, eg. DateTime(‘2000-05’) maps to 0:00 on 1 May 2000.

_datetime_attrs = ('year', 'month', 'day', 'hour', 'minute', 'second')
__init__(*args, **kwargs)[source]

Init method for Date.

_left
_lower
_upper
_right
classmethod _parse_datetime(dt)[source]
classmethod _parse_input_string(s)[source]

Parse date strings in YYYY-MM-DD or YYYYMMDDHH formats.

format(precision=None)[source]
isoformat()[source]
_tuple_compare(other, func)[source]
class src.datelabel.DateFrequency(quantity, unit=None)[source]

Bases: datetime.timedelta

Class representing a date frequency or period.

Note

Period lengths are not defined accurately, eg. a year is taken as 365 days and a month is taken as 30 days.

classmethod _parse_input_string(quantity, unit)[source]
classmethod _get_timedelta_kwargs(q, s)[source]
format()[source]
format_local()[source]