Skip to content

Dates & Periods

The Period class represents a calendar period composed of months and days. Use the period factory function to create instances from a period string.

Period strings

A period string combines one or more components, each a number followed by a unit letter:

Unit Meaning
Y Years
M Months
W Weeks
D Days

Examples: "1Y", "6M", "2W", "3D", "1Y6M", "2W3D".

Usage

import ccy

p = ccy.period("1Y6M")
str(p)       # "1Y6M"
p.years      # 1
p.months     # 6
p.totaldays  # 390

Arithmetic with strings or other Period objects:

p = ccy.period("1M")
p += "2W"    # Period("1M2W")
p += "3M"    # Period("4M2W")
p -= "1W"    # Period("4M1W")

Comparison:

ccy.period("1Y") > ccy.period("6M")   # True
ccy.period("12M") == ccy.period("1Y") # True

Class reference

ccy.dates.period.Period

Period(months=0, days=0)
Source code in ccy/dates/period.py
def __init__(self, months: int = 0, days: int = 0) -> None:
    self._months = months
    self._days = days

years property

years

months property

months

weeks property

weeks

days property

days

totaldays property

totaldays

make classmethod

make(data)
Source code in ccy/dates/period.py
@classmethod
def make(cls, data: Any) -> Self:
    if isinstance(data, cls):
        return data
    elif isinstance(data, str):
        return cls().add_tenure(data)
    else:
        raise TypeError("Cannot convert %s to Period" % data)

isempty

isempty()
Source code in ccy/dates/period.py
def isempty(self) -> bool:
    return self._months == 0 and self._days == 0

add_days

add_days(days)
Source code in ccy/dates/period.py
def add_days(self, days: int) -> None:
    self._days += days

add_weeks

add_weeks(weeks)
Source code in ccy/dates/period.py
def add_weeks(self, weeks: int) -> None:
    self._days += int(7 * weeks)

add_months

add_months(months)
Source code in ccy/dates/period.py
def add_months(self, months: int) -> None:
    self._months += months

add_years

add_years(years)
Source code in ccy/dates/period.py
def add_years(self, years: int) -> None:
    self._months += int(12 * years)

components

components()

The period string

Source code in ccy/dates/period.py
def components(self) -> str:
    """The period string"""
    p = ""
    neg = self.totaldays < 0
    y = self.years
    m = self.months
    w = self.weeks
    d = self.days
    if y:
        p = "%sY" % abs(y)
    if m:
        p = "%s%sM" % (p, abs(m))
    if w:
        p = "%s%sW" % (p, abs(w))
    if d:
        p = "%s%sD" % (p, abs(d))
    return "-" + p if neg else p

simple

simple()

A string representation with only one period delimiter.

Source code in ccy/dates/period.py
def simple(self) -> str:
    """A string representation with only one period delimiter."""
    if self._days:
        return "%sD" % self.totaldays
    elif self.months:
        return "%sM" % self._months
    elif self.years:
        return "%sY" % self.years
    else:
        return ""

add_tenure

add_tenure(pstr)
Source code in ccy/dates/period.py
def add_tenure(self, pstr: str) -> Self:
    if isinstance(pstr, self.__class__):
        self._months += pstr._months
        self._days += pstr._days
        return self
    st = str(pstr).upper()
    done = False
    sign = 1
    while not done:
        if not st:
            done = True
        else:
            ip = find_first_of(st, "DWMY")
            if ip == -1:
                raise ValueError("Unknown period %s" % pstr)
            p = st[ip]
            v = int(st[:ip])
            sign = sign if v > 0 else -sign
            v = sign * abs(v)
            if p == "D":
                self.add_days(v)
            elif p == "W":
                self.add_weeks(v)
            elif p == "M":
                self.add_months(v)
            elif p == "Y":
                self.add_years(v)
            ip += 1
            st = st[ip:]
    return self