Toolbox to handle date intervals.
A Period
is a triple (unit
, start
, size
).
Either year
, month
, day
or eternity
.
The amount of unit
, starting at start
, at least 1
.
Examples
>>> instant = Instant((2021, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> repr(Period)
"<class 'openfisca_core.periods.period_.Period'>"
>>> repr(period)
"Period((<DateUnit.YEAR: 'year'>, Instant((2021, 10, 1)), 3))"
>>> str(period)
'year:2021-10:3'
>>> dict([period, instant])
Traceback (most recent call last):
ValueError: dictionary update sequence element #0 has length 3...
>>> list(period)
[<DateUnit.YEAR: 'year'>, Instant((2021, 10, 1)), 3]
>>> period[0]
<DateUnit.YEAR: 'year'>
>>> period[0] in period
True
>>> len(period)
3
>>> period == Period((DateUnit.YEAR, instant, 3))
True
>>> period != Period((DateUnit.YEAR, instant, 3))
False
>>> period > Period((DateUnit.YEAR, instant, 3))
False
>>> period < Period((DateUnit.YEAR, instant, 3))
False
>>> period >= Period((DateUnit.YEAR, instant, 3))
True
>>> period <= Period((DateUnit.YEAR, instant, 3))
True
>>> period.days
1096
>>> period.size_in_months
36
>>> period.size_in_days
1096
>>> period.stop
Instant((2024, 9, 30))
>>> period.unit
<DateUnit.YEAR: 'year'>
>>> period.last_3_months
Period((<DateUnit.MONTH: 'month'>, Instant((2021, 7, 1)), 3))
>>> period.last_month
Period((<DateUnit.MONTH: 'month'>, Instant((2021, 9, 1)), 1))
>>> period.last_year
Period((<DateUnit.YEAR: 'year'>, Instant((2020, 1, 1)), 1))
>>> period.n_2
Period((<DateUnit.YEAR: 'year'>, Instant((2019, 1, 1)), 1))
>>> period.this_year
Period((<DateUnit.YEAR: 'year'>, Instant((2021, 1, 1)), 1))
>>> period.first_month
Period((<DateUnit.MONTH: 'month'>, Instant((2021, 10, 1)), 1))
>>> period.first_day
Period((<DateUnit.DAY: 'day'>, Instant((2021, 10, 1)), 1))
Since a period is a triple it can be used as a dictionary key.
Returns True
if the period contains other
.
For instance, period(2015)
contains period(2015-01)
.
The date representation of the Period
start date.
Examples
>>> instant = Instant((2021, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 1))
>>> period.date
Date(2021, 10, 1)
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.date
Traceback (most recent call last):
ValueError: "date" is undefined for a period of size > 1: year:2021-10:3.
Same as size_in_days
.
Return the list of periods of unit unit
contained in self.
Examples
>>> period = Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1))
>>> period.get_subperiods(DateUnit.MONTH)
[Period((<DateUnit.MONTH: 'month'>, Instant((2021, 1, 1)), 1)),...]
>>> period = Period((DateUnit.YEAR, Instant((2021, 1, 1)), 2))
>>> period.get_subperiods(DateUnit.YEAR)
[Period((<DateUnit.YEAR: 'year'>, Instant((2021, 1, 1)), 1)), P...]
Increment (or decrement) the given period with offset units.
Examples
>>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(1)
Period((<DateUnit.DAY: 'day'>, Instant((2021, 1, 2)), 365))
>>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(
... 1, DateUnit.DAY
... )
Period((<DateUnit.DAY: 'day'>, Instant((2021, 1, 2)), 365))
>>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(
... 1, DateUnit.MONTH
... )
Period((<DateUnit.DAY: 'day'>, Instant((2021, 2, 1)), 365))
>>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(
... 1, DateUnit.YEAR
... )
Period((<DateUnit.DAY: 'day'>, Instant((2022, 1, 1)), 365))
>>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(1)
Period((<DateUnit.MONTH: 'month'>, Instant((2021, 2, 1)), 12))
>>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(
... 1, DateUnit.DAY
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2021, 1, 2)), 12))
>>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(
... 1, DateUnit.MONTH
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2021, 2, 1)), 12))
>>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(
... 1, DateUnit.YEAR
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2022, 1, 1)), 12))
>>> Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)).offset(1)
Period((<DateUnit.YEAR: 'year'>, Instant((2022, 1, 1)), 1))
>>> Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)).offset(
... 1, DateUnit.DAY
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2021, 1, 2)), 1))
>>> Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)).offset(
... 1, DateUnit.MONTH
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2021, 2, 1)), 1))
>>> Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)).offset(
... 1, DateUnit.YEAR
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2022, 1, 1)), 1))
>>> Period((DateUnit.DAY, Instant((2011, 2, 28)), 1)).offset(1)
Period((<DateUnit.DAY: 'day'>, Instant((2011, 3, 1)), 1))
>>> Period((DateUnit.MONTH, Instant((2011, 2, 28)), 1)).offset(1)
Period((<DateUnit.MONTH: 'month'>, Instant((2011, 3, 28)), 1))
>>> Period((DateUnit.YEAR, Instant((2011, 2, 28)), 1)).offset(1)
Period((<DateUnit.YEAR: 'year'>, Instant((2012, 2, 28)), 1))
>>> Period((DateUnit.DAY, Instant((2011, 3, 1)), 1)).offset(-1)
Period((<DateUnit.DAY: 'day'>, Instant((2011, 2, 28)), 1))
>>> Period((DateUnit.MONTH, Instant((2011, 3, 1)), 1)).offset(-1)
Period((<DateUnit.MONTH: 'month'>, Instant((2011, 2, 1)), 1))
>>> Period((DateUnit.YEAR, Instant((2011, 3, 1)), 1)).offset(-1)
Period((<DateUnit.YEAR: 'year'>, Instant((2010, 3, 1)), 1))
>>> Period((DateUnit.DAY, Instant((2014, 1, 30)), 1)).offset(3)
Period((<DateUnit.DAY: 'day'>, Instant((2014, 2, 2)), 1))
>>> Period((DateUnit.MONTH, Instant((2014, 1, 30)), 1)).offset(3)
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 4, 30)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 1, 30)), 1)).offset(3)
Period((<DateUnit.YEAR: 'year'>, Instant((2017, 1, 30)), 1))
>>> Period((DateUnit.DAY, Instant((2021, 1, 1)), 365)).offset(-3)
Period((<DateUnit.DAY: 'day'>, Instant((2020, 12, 29)), 365))
>>> Period((DateUnit.MONTH, Instant((2021, 1, 1)), 12)).offset(-3)
Period((<DateUnit.MONTH: 'month'>, Instant((2020, 10, 1)), 12))
>>> Period((DateUnit.YEAR, Instant((2014, 1, 1)), 1)).offset(-3)
Period((<DateUnit.YEAR: 'year'>, Instant((2011, 1, 1)), 1))
>>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 1)).offset(
... "first-of", DateUnit.MONTH
... )
Period((<DateUnit.DAY: 'day'>, Instant((2014, 2, 1)), 1))
>>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 1)).offset(
... "first-of", DateUnit.YEAR
... )
Period((<DateUnit.DAY: 'day'>, Instant((2014, 1, 1)), 1))
>>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 4)).offset(
... "first-of", DateUnit.MONTH
... )
Period((<DateUnit.DAY: 'day'>, Instant((2014, 2, 1)), 4))
>>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 4)).offset(
... "first-of", DateUnit.YEAR
... )
Period((<DateUnit.DAY: 'day'>, Instant((2014, 1, 1)), 4))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset("first-of")
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 1)), 1))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset(
... "first-of", DateUnit.MONTH
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 1)), 1))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset(
... "first-of", DateUnit.YEAR
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 1, 1)), 1))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset("first-of")
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 1)), 4))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset(
... "first-of", DateUnit.MONTH
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 1)), 4))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset(
... "first-of", DateUnit.YEAR
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 1, 1)), 4))
>>> Period((DateUnit.YEAR, Instant((2014, 1, 30)), 1)).offset("first-of")
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 1, 1)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 1, 30)), 1)).offset(
... "first-of", DateUnit.MONTH
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 1, 1)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 1, 30)), 1)).offset(
... "first-of", DateUnit.YEAR
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 1, 1)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("first-of")
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 1, 1)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset(
... "first-of", DateUnit.MONTH
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 2, 1)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset(
... "first-of", DateUnit.YEAR
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 1, 1)), 1))
>>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 1)).offset(
... "last-of", DateUnit.MONTH
... )
Period((<DateUnit.DAY: 'day'>, Instant((2014, 2, 28)), 1))
>>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 1)).offset(
... "last-of", DateUnit.YEAR
... )
Period((<DateUnit.DAY: 'day'>, Instant((2014, 12, 31)), 1))
>>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 4)).offset(
... "last-of", DateUnit.MONTH
... )
Period((<DateUnit.DAY: 'day'>, Instant((2014, 2, 28)), 4))
>>> Period((DateUnit.DAY, Instant((2014, 2, 3)), 4)).offset(
... "last-of", DateUnit.YEAR
... )
Period((<DateUnit.DAY: 'day'>, Instant((2014, 12, 31)), 4))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset("last-of")
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 28)), 1))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset(
... "last-of", DateUnit.MONTH
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 28)), 1))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 1)).offset(
... "last-of", DateUnit.YEAR
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 12, 31)), 1))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset("last-of")
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 28)), 4))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset(
... "last-of", DateUnit.MONTH
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 28)), 4))
>>> Period((DateUnit.MONTH, Instant((2014, 2, 3)), 4)).offset(
... "last-of", DateUnit.YEAR
... )
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 12, 31)), 4))
>>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("last-of")
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 12, 31)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 1, 1)), 1)).offset(
... "last-of", DateUnit.MONTH
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 1, 31)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset(
... "last-of", DateUnit.YEAR
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 12, 31)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset("last-of")
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 12, 31)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset(
... "last-of", DateUnit.MONTH
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 2, 28)), 1))
>>> Period((DateUnit.YEAR, Instant((2014, 2, 3)), 1)).offset(
... "last-of", DateUnit.YEAR
... )
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 12, 31)), 1))
The size
of the Period
.
Example
>>> instant = Instant((2021, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.size
3
The size
of the Period
in days.
Examples
>>> instant = Instant((2019, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.size_in_days
1096
>>> period = Period((DateUnit.MONTH, instant, 3))
>>> period.size_in_days
92
The size
of the Period
in months.
Examples
>>> instant = Instant((2021, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.size_in_months
36
>>> period = Period((DateUnit.DAY, instant, 3))
>>> period.size_in_months
Traceback (most recent call last):
ValueError: Can't calculate number of months in a day.
The size
of the Period
in weekdays.
Examples
>>> instant = Instant((2019, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.size_in_weekdays
1092
>>> period = Period((DateUnit.WEEK, instant, 3))
>>> period.size_in_weekdays
21
The size
of the Period
in weeks.
Examples
>>> instant = Instant((2019, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.size_in_weeks
156
>>> period = Period((DateUnit.YEAR, instant, 5))
>>> period.size_in_weeks
261
The size
of the Period
in years.
Examples
>>> instant = Instant((2021, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.size_in_years
3
>>> period = Period((DateUnit.MONTH, instant, 3))
>>> period.size_in_years
Traceback (most recent call last):
ValueError: Can't calculate number of years in a month.
The Instant
at which the Period
starts.
Example
>>> instant = Instant((2021, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.start
Instant((2021, 10, 1))
Return the last day of the period as an Instant instance.
Examples
>>> Period((DateUnit.YEAR, Instant((2022, 1, 1)), 1)).stop
Instant((2022, 12, 31))
>>> Period((DateUnit.MONTH, Instant((2022, 1, 1)), 12)).stop
Instant((2022, 12, 31))
>>> Period((DateUnit.DAY, Instant((2022, 1, 1)), 365)).stop
Instant((2022, 12, 31))
>>> Period((DateUnit.YEAR, Instant((2012, 2, 29)), 1)).stop
Instant((2013, 2, 27))
>>> Period((DateUnit.MONTH, Instant((2012, 2, 29)), 1)).stop
Instant((2012, 3, 28))
>>> Period((DateUnit.DAY, Instant((2012, 2, 29)), 1)).stop
Instant((2012, 2, 29))
>>> Period((DateUnit.YEAR, Instant((2012, 2, 29)), 2)).stop
Instant((2014, 2, 27))
>>> Period((DateUnit.MONTH, Instant((2012, 2, 29)), 2)).stop
Instant((2012, 4, 28))
>>> Period((DateUnit.DAY, Instant((2012, 2, 29)), 2)).stop
Instant((2012, 3, 1))
The unit
of the Period
.
Example
>>> instant = Instant((2021, 10, 1))
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> period.unit
<DateUnit.YEAR: 'year'>
An instant in time (year, month, day).
An Instant
represents the most atomic and indivisible
legislation’s date unit.
Current implementation considers this unit to be a day, so
instants
can be thought of as “day dates”.
Examples
>>> instant = Instant((2021, 9, 13))
>>> repr(Instant)
"<class 'openfisca_core.periods.instant_.Instant'>"
>>> repr(instant)
'Instant((2021, 9, 13))'
>>> str(instant)
'2021-09-13'
>>> dict([(instant, (2021, 9, 13))])
{Instant((2021, 9, 13)): (2021, 9, 13)}
>>> list(instant)
[2021, 9, 13]
>>> instant[0]
2021
>>> instant[0] in instant
True
>>> len(instant)
3
>>> instant == (2021, 9, 13)
True
>>> instant != (2021, 9, 13)
False
>>> instant > (2020, 9, 13)
True
>>> instant < (2020, 9, 13)
False
>>> instant >= (2020, 9, 13)
True
>>> instant <= (2020, 9, 13)
False
>>> instant.year
2021
>>> instant.month
9
>>> instant.day
13
>>> instant.date
Date(2021, 9, 13)
>>> year, month, day = instant
Build a new instant, aka a triple of integers (year, month, day).
value (object) – An instant-like
object.
:obj:`.Instant` – A new instant.
:exc:`ValueError` – When the arguments were invalid, like “2021-32-13”.
Examples
>>> instant((2021,))
Instant((2021, 1, 1))
>>> instant((2021, 9))
Instant((2021, 9, 1))
>>> instant(datetime.date(2021, 9, 16))
Instant((2021, 9, 16))
>>> instant(Instant((2021, 9, 16)))
Instant((2021, 9, 16))
>>> instant(Period((DateUnit.YEAR, Instant((2021, 9, 16)), 1)))
Instant((2021, 9, 16))
>>> instant(2021)
Instant((2021, 1, 1))
>>> instant("2021")
Instant((2021, 1, 1))
>>> instant([2021])
Instant((2021, 1, 1))
>>> instant([2021, 9])
Instant((2021, 9, 1))
>>> instant(None)
Traceback (most recent call last):
openfisca_core.periods._errors.InstantError: 'None' is not a valid i...
Returns the date representation of an Instant
.
None – When instant
is None.
datetime.date – Otherwise.
Examples
>>> instant_date(Instant((2021, 1, 1)))
Date(2021, 1, 1)
Define a key in order to sort periods by length.
It uses two aspects: first, unit
, then, size
.
:obj:`str` – A string.
Examples
>>> instant = Instant((2021, 9, 14))
>>> period = Period((DateUnit.DAY, instant, 1))
>>> key_period_size(period)
'100_1'
>>> period = Period((DateUnit.YEAR, instant, 3))
>>> key_period_size(period)
'300_3'
Build a new period, aka a triple (unit, start_instant, size).
value (object
) – A period-like
object.
:obj:`.Period` – A period.
:exc:`ValueError` – When the arguments were invalid, like “2021-32-13”.
Examples
>>> period(Period((DateUnit.YEAR, Instant((2021, 1, 1)), 1)))
Period((<DateUnit.YEAR: 'year'>, Instant((2021, 1, 1)), 1))
>>> period(Instant((2021, 1, 1)))
Period((<DateUnit.DAY: 'day'>, Instant((2021, 1, 1)), 1))
>>> period(DateUnit.ETERNITY)
Period((<DateUnit.ETERNITY: 'eternity'>, Instant((-1, -1, -1)), -1))
>>> period(2021)
Period((<DateUnit.YEAR: 'year'>, Instant((2021, 1, 1)), 1))
>>> period("2014")
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 1, 1)), 1))
>>> period("year:2014")
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 1, 1)), 1))
>>> period("month:2014-02")
Period((<DateUnit.MONTH: 'month'>, Instant((2014, 2, 1)), 1))
>>> period("year:2014-02")
Period((<DateUnit.YEAR: 'year'>, Instant((2014, 2, 1)), 1))
>>> period("day:2014-02-02")
Period((<DateUnit.DAY: 'day'>, Instant((2014, 2, 2)), 1))
>>> period("day:2014-02-02:3")
Period((<DateUnit.DAY: 'day'>, Instant((2014, 2, 2)), 3))