Source code for businessdate.basedate

# -*- coding: utf-8 -*-

# businessdate
# ------------
# Python library for generating business dates for fast date operations
# and rich functionality.
#
# Author:   sonntagsgesicht, based on a fork of Deutsche Postbank [pbrisk]
# Version:  0.5, copyright Wednesday, 18 September 2019
# Website:  https://github.com/sonntagsgesicht/businessdate
# License:  Apache License 2.0 (see LICENSE file)


from datetime import date, timedelta

from .ymd import from_excel_to_ymd, from_ymd_to_excel


[docs]class BaseDateFloat(float): """ native :class:`float` backed base class for a performing date calculations counting days since Jan, 1st 1900 """ def __new__(cls, x=0): new = super(BaseDateFloat, cls).__new__(cls, x) new._ymd = None return new # --- property methods --------------------------------------------------- @property def day(self): if not self._ymd: self._ymd = self.to_ymd() return self._ymd[2] @property def month(self): if not self._ymd: self._ymd = self.to_ymd() return self._ymd[1] @property def year(self): if not self._ymd: self._ymd = self.to_ymd() return self._ymd[0]
[docs] def weekday(self): return self.to_date().weekday()
# --- constructor method -------------------------------------------------
[docs] @classmethod def from_ymd(cls, year, month, day): """ creates instance from a :class:`tuple` of :class:`int` items `(year, month, day)` """ return cls(from_ymd_to_excel(year, month, day))
[docs] @classmethod def from_date(cls, d): """ creates instance from a :class:`datetime.date` object `d` """ return cls.from_ymd(d.year, d.month, d.day)
[docs] @classmethod def from_float(cls, x): """ creates from a :class:`float` `x` counting the days since Jan, 1st 1900 """ return cls(x)
# --- cast method --------------------------------------------------------
[docs] def to_ymd(self): """ returns the :class:`tuple` of :class:`int` items `(year, month, day)` """ if not self._ymd: self._ymd = from_excel_to_ymd(int(self)) return self._ymd
[docs] def to_date(self): """ returns `datetime.date(year, month, day)` """ if not self._ymd: self._ymd = self.to_ymd() return date(*self._ymd)
[docs] def to_float(self): """ returns :class:`float` counting the days since Jan, 1st 1900 """ return float(self)
# --- calculation methods ------------------------------------------------ def _add_days(self, n): self._ymd = None return self.__class__(super(BaseDateFloat, self).__add__(n)) def _diff_in_days(self, d): return super(BaseDateFloat, d).__sub__(float(self))
[docs]class BaseDateDatetimeDate(date): """ :class:`datetime.date` backed base class for a performing date calculations """ # --- constructor method -------------------------------------------------
[docs] @classmethod def from_ymd(cls, year, month, day): """ creates instance from a :class:`tuple` of :class:`int` items `(year, month, day)` """ return cls(year, month, day)
[docs] @classmethod def from_date(cls, d): """ creates instance from a :class:`datetime.date` object `d` """ return cls.from_ymd(d.year, d.month, d.day)
[docs] @classmethod def from_float(cls, x): """ creates from a :class:`float` `x` counting the days since Jan, 1st 1900 """ y, m, d = from_excel_to_ymd(x) return cls.from_ymd(y, m, d)
# --- cast method --------------------------------------------------------
[docs] def to_ymd(self): """ returns the :class:`tuple` of :class:`int` items `(year, month, day)` """ return self.year, self.month, self.day
[docs] def to_date(self): """ returns `datetime.date(year, month, day)` """ return date(*self.to_ymd())
[docs] def to_float(self): """ returns :class:`float` counting the days since Jan, 1st 1900 """ return float(from_ymd_to_excel(*self.to_ymd()))
[docs] def to_serializable(self, *args, **kwargs): return str(self)
# --- calculation methods ------------------------------------------------ def _add_days(self, days_int): # return super(self.__class__, self).__add__(timedelta(days_int)) res = super(BaseDateDatetimeDate, self).__add__(timedelta(days_int)) return self.__class__.from_ymd(res.year, res.month, res.day) def _diff_in_days(self, end): delta = super(BaseDateDatetimeDate, end).__sub__(self) return float(delta.days)