API reference

This page documents bizdays 2.0. Every example on this page runs as a test, so the outputs shown are the real outputs. The examples share one session that starts here:

>>> import numpy as np
>>> import pandas as pd
>>> import bizdays
>>> from bizdays import Calendar, DateOutOfRange, list_calendars
>>> cal = Calendar.load(name="ANBIMA")

Numbers, partial strings such as "2024-01", and numpy.datetime64 values with unit Y, M or W are not dates and raise ValueError. Time-zone-aware values use their wall-clock date.

See also:

Public API

The public API is exactly the names in bizdays.__all__, with their documented methods, properties and exceptions:

>>> bizdays.__all__
['Calendar', 'list_calendars', 'DateOutOfRange']

Every submodule (bizdays.calendar, bizdays.dateindex, bizdays.utils, bizdays.date, bizdays.getdate_parser, bizdays.calendarfile, bizdays.external) is internal and may change without notice.

exception bizdays.DateOutOfRange(message: str, positions: _Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] = (0,))

A date, input or result, lies outside the calendar range.

positions is a sorted 1-D int64 array with the index of every bad element, counted in the result of the call.

Output types

Methods return NumPy values, never pandas objects or Python dates. When every argument is a single value, the result is a NumPy scalar. When any argument is a vector, the result is a 1-D NumPy array.

Result

Methods

Type

Missing value

Dates

offset, following, preceding, modified_*, adjust_*, seq, getdate

numpy.datetime64 with unit D, or an array of datetime64[D]

NaT (“not a time”)

Counts

bizdays, diff, getbizdays

numpy.float64, or an array of float64

NaN (“not a number”)

Flags

isbizday, inrange

numpy.bool_; a vector is always a numpy.ma.MaskedArray with fill_value=False

numpy.ma.masked for a scalar, a masked element in a vector

Properties

startdate, enddate, holidays, weekdays, name, financial

Python types: datetime.date, list, tuple, str, bool

none

A masked array is a NumPy array with a second array, the mask, that marks the missing elements.

Counts are float64 even when nothing is missing, because NumPy has no integer type with a missing value. Use .item() for a Python number:

>>> cal.bizdays("2024-01-02", "2024-01-05")
np.float64(3.0)
>>> cal.bizdays("2024-01-02", "2024-01-05").item()
3.0
>>> x = cal.bizdays(["2024-01-02", None], "2024-01-05")
>>> x
array([ 3., nan])

NaN compares False with any number, so a missing count is never > 0. Drop the NaN values before you turn counts into integers:

>>> x > 0
array([ True, False])
>>> x[~np.isnan(x)].astype(int)
array([3])

Properties keep Python types:

>>> cal.startdate
datetime.date(2000, 1, 1)

Results are positional: a pandas Series in gives a NumPy array out, and the Series index is not kept. Assign a result straight to a column. Never wrap it in pd.Series(result) without index=:

>>> df = pd.DataFrame({"start": ["2024-01-02", "2024-01-03"]}, index=[10, 20])
>>> df["du"] = cal.bizdays(df.start, "2024-01-05")
>>> df
         start   du
10  2024-01-02  3.0
20  2024-01-03  2.0
>>> pd.Series(cal.bizdays(df.start, "2024-01-05"), index=df.index)
10    3.0
20    2.0
dtype: float64

Missing values

A missing value is anything pandas.isna reports as missing (None, NaN, NaT, pd.NA), plus a masked element. Missing in gives missing out, element by element:

>>> cal.isbizday(["2024-01-01", None, "2024-01-02"])
masked_array(data=[False, --, True],
             mask=[False,  True, False],
       fill_value=False)
>>> cal.isbizday(None)
masked
>>> cal.bizdays(None, "2024-01-05")
np.float64(nan)
>>> cal.offset(["2024-01-02", None], 1)
array(['2024-01-03', 'NaT'], dtype='datetime64[D]')
>>> cal.diff(["2024-01-02", "2024-01-05", None, "2024-01-10"])
array([ 3., nan, nan])

seq is the exception: a missing end raises ValueError. An empty string is not missing; it is an invalid date and raises ValueError. Missing values are never out of range.

Vector arguments

These rules apply to the methods with two arguments that can be vectors: bizdays, offset, getdate and getbizdays. A single value (a scalar, or a vector of length 1) is used for every element. Equal lengths pair element by element:

>>> cal.offset("2024-01-05", [1, 2])
array(['2024-01-08', '2024-01-09'], dtype='datetime64[D]')

Any other pair of lengths raises ValueError:

>>> cal.bizdays(["2024-01-02", "2024-01-03"], ["2024-01-04", "2024-01-05", "2024-01-08"])
Traceback (most recent call last):
...
ValueError: date_from has length 2 and date_to has length 3; ...

To repeat the shorter input on purpose, use np.tile or np.repeat.

Errors

Situation

Error

A date (input or result) outside the calendar range; a getbizdays period not fully inside it

DateOutOfRange, a subclass of ValueError, with positions

Invalid date string, number given as a date, numpy.datetime64 with unit Y/M/W given as a date, 2-D input, invalid count, year or month, invalid getdate expression or ref, a getdate date that does not exist in its period, seq with a vector or a missing end, bad constructor arguments, unknown packaged or provider calendar, a .cal file, a value other than the default for adjust.from or adjust.to in a JSON file

ValueError

Vector lengths that differ, when neither is 1

ValueError

Calendar file not found

FileNotFoundError

Optional provider not installed

ImportError, which names the extra to install

So except ValueError catches every bad-input problem, including dates out of range. Values of the wrong type also raise ValueError, not TypeError. Python’s own errors for a wrong call, such as a missing argument, are not covered by this table.

Calendar discovery

bizdays.list_calendars() → CalendarListing

List the packaged calendars and supported optional calendar integrations.

Returns:

A dictionary containing the packaged calendars and integration metadata.

Return type:

dict

Example:

>>> info = list_calendars()
>>> info["packaged"]
['ANBIMA', 'B3', 'Actual']
>>> sorted(info["pandas_market_calendars"])
['available', 'calendars', 'prefix']
>>> info["workalendar"]["prefix"]
'WORK/'

For each provider (pandas_market_calendars, exchange_calendars, workalendar), available says whether it is installed and calendars lists the names you can load with its prefix.

Calendar construction

class bizdays.Calendar(holidays: Sequence[DateScalar] | None = None, weekdays: Sequence[str] | None = None, startdate: DateScalar | None = None, enddate: DateScalar | None = None, name: str | None = '', financial: bool = True)

Calendar class

Calendar representation where holidays and nonworking weekdays are defined.

name
Type:

str

holidays
Type:

list of datetime.date

enddate
Type:

datetime.date

startdate
Type:

datetime.date

weekdays
Type:

tuple of str

financial
Type:

bool

Parameters:
  • holidays (1-D sequence of str, datetime.date, datetime.datetime, pandas.Timestamp or numpy.datetime64) – Holidays; missing values are not allowed. Holidays outside startdate..enddate are ignored.

  • weekdays (list) –

    A list with weekdays representing nonworking days.

    Accepts full or 3-letter English names in any case, such as ‘Saturday’, ‘sat’ or ‘SUN’. Duplicates are removed. Giving holidays with weekdays=None emits a UserWarning, as in R bizdays; pass weekdays=[] for a calendar without nonworking weekdays.

  • startdate (str, datetime.date, datetime.datetime, pandas.Timestamp or numpy.datetime64) – Calendar’s start date

  • enddate (str, datetime.date, datetime.datetime, pandas.Timestamp or numpy.datetime64) – Calendar’s end date

  • name (str) – Calendar’s name

  • financial (bool) – Defines a financial calendar

Raises:

ValueError – For an invalid weekday name, startdate after enddate, a calendar without business days in its whole range, or an argument of the wrong type (for example weekdays not a list, name not a string, financial not a bool).

Create a calendar in memory when you already have the holidays and nonworking weekdays available in Python:

>>> custom = Calendar(
...     holidays=["2024-01-01", "2024-12-25"],
...     weekdays=["Saturday", "Sunday"],
...     startdate="2024-01-01",
...     enddate="2024-12-31",
...     name="Example",
...     financial=True,
... )
>>> custom.weekdays
('Saturday', 'Sunday')
>>> custom.enddate
datetime.date(2024, 12, 31)

Constructor notes:

  • holidays accepts ISO strings, datetime.date, datetime.datetime, numpy.datetime64, and pandas timestamps

  • weekdays lists the nonworking weekdays

  • when startdate and enddate are omitted, they are inferred from the holiday range

  • calendars without holidays default to a broad built-in date range

  • holidays outside an explicit startdate..enddate are ignored

  • ValueError for startdate after enddate, a calendar without business days, or an invalid weekday name

  • holidays with weekdays=None emit a UserWarning; pass weekdays=[] for a calendar without nonworking weekdays

Calendar range

A calendar covers startdate..enddate, both ends included. Any input date outside that range, or any result that would fall outside it, raises DateOutOfRange. One bad element fails the whole call: there are no partial results, and dates are never clamped or wrapped. offset past either end, following past the end and preceding before the start all raise. Missing values are never out of range.

The error message names the first bad element by its inputs and says how many elements are bad. DateOutOfRange.positions is a sorted int64 array with the index of every bad element in the result (after the length rules); a call with only scalars gives [0].

Calendar.inrange(dates: DateScalar) → bool | MaskedConstant
Calendar.inrange(dates: Vector) → MaskedArray[Any, dtype[bool]]

Checks if the given dates lie inside the calendar range.

Use it to check input dates before a call; it never raises DateOutOfRange. Results that leave the range (offset, following, getdate) cannot be checked in advance: catch DateOutOfRange and read its positions instead.

Parameters:

dates (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be checked

Returns:

True where the date lies inside startdate..enddate, both ends included. Output rules as for isbizday(): a vector result is a masked array with fill_value=False; a missing scalar gives numpy.ma.masked.

Return type:

numpy.bool_ or numpy.ma.MaskedArray

>>> cal.inrange("2100-01-01")
np.False_
>>> cal.inrange(["1999-12-31", "2024-01-02", None])
masked_array(data=[False, True, --],
             mask=[False, False,  True],
       fill_value=False)

Range recipes

Check input dates before a call with Calendar.inrange(), and compute only the rows that are inside the range. filled(False) turns missing flags into False:

>>> df = pd.DataFrame({"start": ["2024-01-02", "2024-01-03"], "maturity": ["2024-06-15", "2100-01-03"]})
>>> ok = cal.inrange(df.maturity).filled(False)
>>> df.loc[ok, "du"] = cal.bizdays(df.start[ok], df.maturity[ok])
>>> df
        start    maturity     du
0  2024-01-02  2024-06-15  113.0
1  2024-01-03  2100-01-03    NaN

Results cannot be checked in advance, so catch the error and use positions:

>>> try:
...     cal.offset(["2024-01-02", "2099-12-20", "2099-12-22"], [1, 5, 10])
... except DateOutOfRange as e:
...     print(e.positions)
[1 2]

Loading calendars

classmethod Calendar.load(*, name: str) → Calendar
classmethod Calendar.load(*, filename: str) → Calendar

Load a packaged, provider or JSON calendar.

Give exactly one of name and filename, as keywords.

Parameters:
  • name (str) –

    Name of the calendar. Packaged calendars delivered with the package are:

    • B3

    • ANBIMA

    • Actual

    Calendars from pandas_market_calendars can also be loaded with the prefix “PMC/<calendar name>” when that optional dependency is installed.

    Calendars from exchange_calendars can also be loaded with the prefix “XCAL/<calendar name>” when that optional dependency is installed.

    Calendars from workalendar can also be loaded with the prefix “WORK/<calendar code>” when that optional dependency is installed.

  • filename (str) – JSON calendar file using the R-bizdays-style schema.

Returns:

A Calendar object.

Return type:

Calendar

Raises:
  • ValueError – Both or neither of name and filename; name not a string or filename not a string or path; an unknown packaged or provider calendar; a v1 .cal file; invalid JSON content, including a value other than the default for adjust.from ("following") or adjust.to ("preceding").

  • FileNotFoundError – filename does not exist.

  • ImportError – The provider package for a PMC/, XCAL/ or WORK/ name is not installed. The message names the extra to install: bizdays[pmc], bizdays[xcal] or bizdays[work].

Use Calendar.load() for packaged calendars and JSON files:

>>> b3 = Calendar.load(name="B3")
>>> b3.enddate
datetime.date(2099, 12, 31)
>>> Calendar.load(name="Actual").startdate
datetime.date(1900, 1, 1)

A JSON calendar file is loaded with filename=:

custom = Calendar.load(filename="custom-calendar.json")

Packaged calendars shipped with the project:

  • ANBIMA: 2000-01-01 to 2099-12-25. Official ANBIMA holidays up to 2079; later years are projected with the national holiday rule.

  • B3: official B3 holidays for 2000-2026. Years 2027-2099 are projected: ANBIMA holidays, plus December 24, plus the last weekday of the year. Projected years are replaced when B3 publishes them.

  • Actual: no holidays, every day is a business day; 1900-01-01 to 2199-12-31.

Ranges, official and projected years, and how the data is updated: Calendar data.

Calendars from optional providers use a name prefix. Each provider is an optional extra; without it, Calendar.load raises ImportError:

Calendar.load(name="PMC/NYSE")   # pandas_market_calendars: pip install "bizdays[pmc]"
Calendar.load(name="XCAL/XNYS")  # exchange_calendars: pip install "bizdays[xcal]"
Calendar.load(name="WORK/FR")    # workalendar: pip install "bizdays[work]"

The WORK/ names use workalendar registry codes.

Core business-day calculations

bizdays

Calendar.bizdays(date_from: DateScalar, date_to: DateScalar) → float64
Calendar.bizdays(date_from: Vector, date_to: DateScalar | Vector) → ndarray[tuple[Any, ...], dtype[float64]]
Calendar.bizdays(date_from: DateScalar, date_to: Vector) → ndarray[tuple[Any, ...], dtype[float64]]

Calculate the amount of business days between two dates

Vector arguments must have equal lengths, or one of them must have length 1; otherwise ValueError.

Parameters:
  • date_from (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Start date

  • date_to (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – End date

Returns:

The number of business days between date_from and date_to, as float64. A missing input gives NaN. When no business day lies between the two dates the count is 0, unlike R bizdays, which returns -1 or +1. With financial=False the count is the number of business days in the closed interval [date_from, date_to], both ends included, negative when date_from > date_to.

Return type:

numpy.float64 or numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date; or vector lengths that do not match, when neither is 1.

Examples:

>>> cal.bizdays("2013-01-02", "2013-01-31")
np.float64(21.0)
>>> cal.bizdays(["2013-01-02", "2013-01-02"], ["2013-01-31", "2013-02-28"])
array([21., 39.])
>>> cal.bizdays(None, "2024-01-05")
np.float64(nan)

Adjust maturities first

An end date that is not a business day moves to the preceding business day, and a start date that is not a business day moves to the following one. So 2024-06-15, a Saturday, counts like Friday 2024-06-14. A payment due on 2024-06-15 is made on Monday 2024-06-17, so adjust maturities with following first:

>>> cal.bizdays("2024-01-02", "2024-06-15")
np.float64(113.0)
>>> cal.following("2024-06-15")
np.datetime64('2024-06-17')
>>> cal.bizdays("2024-01-02", cal.following("2024-06-15"))
np.float64(114.0)

isbizday

Calendar.isbizday(dt: DateScalar) → bool | MaskedConstant
Calendar.isbizday(dt: Vector) → MaskedArray[Any, dtype[bool]]

Checks if the given dates are business days.

Parameters:

dt (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be checked

Returns:

Returns True if the given date is a business day and False otherwise. A vector result is always a masked array with fill_value=False; a missing scalar gives numpy.ma.masked.

Return type:

numpy.bool_ or numpy.ma.MaskedArray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date.

Examples:

>>> cal.isbizday("2013-01-02")
np.True_
>>> cal.isbizday(["2013-01-01", "2013-01-02"])
masked_array(data=[False, True],
             mask=[False, False],
       fill_value=False)
>>> cal.isbizday([None, "2024-01-02"])
masked_array(data=[--, True],
             mask=[ True, False],
       fill_value=False)

offset

Calendar.offset(dt: DateScalar, n: CountScalar) → datetime64
Calendar.offset(dt: Vector, n: CountScalar | Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]
Calendar.offset(dt: DateScalar, n: Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]

Offsets the given dates by n business days.

Vector arguments must have equal lengths, or one of them must have length 1; otherwise ValueError.

Parameters:
  • dt (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be offset

  • n (int, numpy integer or float with a whole value, or a 1-D sequence of them) – The number of business days to move; negative moves back. NaN is missing and gives NaT.

Returns:

Returns the given dates offset by the given amount of business days.

Return type:

numpy.datetime64 or numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date; a count with a fraction; or vector lengths that do not match, when neither is 1.

Examples:

>>> cal.offset("2013-01-02", 5)
np.datetime64('2013-01-09')
>>> cal.offset(["2013-01-02", "2013-01-03"], [1, -1])
array(['2013-01-03', '2013-01-02'], dtype='datetime64[D]')
>>> cal.offset("2024-01-05", [1, 2])
array(['2024-01-08', '2024-01-09'], dtype='datetime64[D]')

From a day that is not a business day, n=1 is the next business day and n=-1 the previous one (2013-01-01 is a holiday):

>>> cal.offset("2013-01-01", [1, 2, -1, -2])
array(['2013-01-02', '2013-01-03', '2012-12-31', '2012-12-28'],
      dtype='datetime64[D]')

seq

Calendar.seq(date_from: str | date | datetime64, date_to: str | date | datetime64) → ndarray[tuple[Any, ...], dtype[datetime64]]

Sequence of business days.

Parameters:
  • date_from (str, datetime.date, datetime.datetime, pandas.Timestamp or numpy.datetime64) – Start date

  • date_to (str, datetime.date, datetime.datetime, pandas.Timestamp or numpy.datetime64) – End date

Returns:

Returns a NumPy array containing business days only.

Return type:

numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date; a vector; or a missing end.

Examples:

>>> cal.seq("2014-01-02", "2014-01-07")
array(['2014-01-02', '2014-01-03', '2014-01-06', '2014-01-07'],
      dtype='datetime64[D]')
>>> cal.seq("2014-01-07", "2014-01-02")  # reverse order is kept
array(['2014-01-07', '2014-01-06', '2014-01-03', '2014-01-02'],
      dtype='datetime64[D]')

diff

Calendar.diff(dts: Vector) → FloatArray

Compute the number of business days between dates in a given vector of dates.

Parameters:

dts (1-D sequence of str, datetime.date, datetime.datetime, pandas.Timestamp or numpy.datetime64) – Sequence containing the dates to be differenced.

Returns:

The number of business days between consecutive dates, as float64 with NaN for missing values.

Return type:

numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date.

Examples:

>>> cal.diff(["2013-01-02", "2013-01-03", "2013-01-04"])
array([1., 1.])
>>> cal.diff(["2013-01-02"])
array([], dtype=float64)

Date adjustment methods

adjust_next

Calendar.adjust_next(dt: DateScalar) → datetime64
Calendar.adjust_next(dt: Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]

Adjusts the given dates to the next business day

Rolls the given date to the next business day, unless it is a business day.

Parameters:

dt (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be adjusted

Returns:

Returns the next business day if the given date is not a business day.

Return type:

numpy.datetime64 or numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date.

Example:

>>> cal.adjust_next("2013-01-01")
np.datetime64('2013-01-02')

following

Calendar.following(dt: DateScalar) → datetime64
Calendar.following(dt: Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]

Alias of adjust_next().

Parameters:

dt (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be adjusted

Returns:

Returns the next business day if the given date is not a business day.

Return type:

numpy.datetime64 or numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date.

Example:

>>> cal.following("2015-12-25")
np.datetime64('2015-12-28')

modified_following

Calendar.modified_following(dt: DateScalar) → datetime64
Calendar.modified_following(dt: Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]

Adjusts the given dates to the next business day with a small difference.

Rolls the given date to the next business day, unless it happens in the next month, in this case it returns the previous business day.

Parameters:

dt (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be adjusted

Returns:

Returns the next business day unless that would cross into the next month.

Return type:

numpy.datetime64 or numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date.

Example:

>>> cal.modified_following("2022-04-30")
np.datetime64('2022-04-29')

adjust_previous

Calendar.adjust_previous(dt: DateScalar) → datetime64
Calendar.adjust_previous(dt: Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]

Adjusts the given dates to the previous business day

Rolls the given date to the previous business day, unless it is a business day.

Parameters:

dt (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be adjusted

Returns:

Returns the previous business day if the given date is not a business day.

Return type:

numpy.datetime64 or numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date.

Example:

>>> cal.adjust_previous("2013-01-01")
np.datetime64('2012-12-31')

preceding

Calendar.preceding(dt: DateScalar) → datetime64
Calendar.preceding(dt: Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]

Alias of adjust_previous().

Parameters:

dt (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be adjusted

Returns:

Returns the previous business day if the given date is not a business day.

Return type:

numpy.datetime64 or numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date.

Example:

>>> cal.preceding("2014-01-01")
np.datetime64('2013-12-31')

modified_preceding

Calendar.modified_preceding(dt: DateScalar) → datetime64
Calendar.modified_preceding(dt: Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]

Adjusts the given dates to the previous business day with a small difference.

Rolls the given date to the previous business day, unless it happens in the previous month, in this case it returns the following business day.

Parameters:

dt (str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) – Dates to be adjusted

Returns:

Returns the previous business day unless that would cross into the previous month.

Return type:

numpy.datetime64 or numpy.ndarray

Raises:
  • DateOutOfRange – An input date, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – Invalid input, such as a string that is not a full ISO date, or a number given as a date.

Example:

>>> cal.modified_preceding("2015-03-01")
np.datetime64('2015-03-02')

Date expression lookup

getdate

Calendar.getdate(expr: str | None, ref: RefScalar) → datetime64
Calendar.getdate(expr: Vector, ref: RefScalar | Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]
Calendar.getdate(expr: str | None, ref: Vector) → ndarray[tuple[Any, ...], dtype[datetime64]]

Get dates using a month, year, or date reference.

Vector arguments must have equal lengths, or one of them must have length 1; otherwise ValueError.

Parameters:
  • expr (str, or a 1-D sequence of str) – String specifying the date to be returned, such as "first bizday", "next wed", "last day" or "1st bizday before 2nd fri". With a year or month ref it is the n-th day, business day or weekday inside the period (next means the first). With a date ref, <n> day is the date plus n days, <n> bizday is offset(date, n) and <n> <weekday> the n-th one strictly after the date; last (or previous <weekday>) is the one strictly before. Composite expressions need a year or month ref.

  • ref (int, float with a whole value, str, datetime.date, datetime.datetime, pandas.Timestamp, numpy.datetime64, or a 1-D sequence of them) –

    Reference used to resolve the expression. All refs in one call must be of one kind, otherwise ValueError.

    • YYYY-MM strings refer to a month

    • YYYY strings and integers refer to a year

    • date-like values such as YYYY-MM-DD refer to a date

Returns:

Returns dates according to the given reference.

Return type:

numpy.datetime64 or numpy.ndarray

Raises:
  • DateOutOfRange – A ref period, or a result, lies outside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – An invalid expression or ref, refs of more than one kind, a date that does not exist in its period (such as 5th fri in a month with four Fridays), a composite expression with a date ref, or vector lengths that do not match, when neither is 1.

Calendar.getdate(expr, ref) resolves expressions against three kinds of references:

  • month references such as "2002-05"

  • year references such as 2006 or "2006"

  • date references such as "2021-02-10"

All refs in one call must be of one kind (year, month or date); missing refs do not count. Mixing kinds, as in ["2002-01", "2021-02-10"], raises ValueError.

Expressions

Format:

<position> <day>
<position> <day> <before|after> <position> <day>
previous <weekday>

Positions:

  • next, first/1st, second/2nd, third/3rd, last

  • <n> with the right English suffix: 4th, 11th, 21st, 22nd, 23rd. A wrong suffix, such as 2st, raises ValueError; so does 0th.

Days:

  • day, bizday

  • weekdays, as 3-letter or full English names: mon/monday … sun/sunday

Words are case-insensitive. Any other word raises ValueError.

Year or month refs

  • <n> <day> is the n-th day, business day or weekday inside the period; last is the last one, and next means the first.

  • Composite expressions (first day before 15th day, 1st bizday before 2nd fri) work with period refs only. In their first slot, last and next mean 1st. The result may leave the ref period, but not the calendar range.

  • A date that does not exist in its period, such as 5th fri in a month with four Fridays, raises ValueError.

Date refs

  • <n> day is the date plus n days; last day is the day before.

  • <n> bizday is offset(date, n); last bizday is offset(date, -1).

  • <n> <weekday> is the n-th such weekday strictly after the date; last <weekday> and previous <weekday> are the one strictly before.

  • previous works with weekdays and date refs only.

Examples:

>>> cal.getdate("15th day", "2002-05")
np.datetime64('2002-05-15')
>>> cal.getdate(["last day", "last bizday"], "2006")
array(['2006-12-31', '2006-12-29'], dtype='datetime64[D]')
>>> cal.getdate("next wed", "2002-01")  # the first Wednesday
np.datetime64('2002-01-02')
>>> cal.getdate("next wed", "2021-02-10")
np.datetime64('2021-02-17')
>>> cal.getdate("next bizday", "2022-06-18")
np.datetime64('2022-06-20')
>>> cal.getdate("last mon", "2022-06-20")
np.datetime64('2022-06-13')
>>> cal.getdate("first bizday", ["2002-01", "2002-02"])
array(['2002-01-02', '2002-02-01'], dtype='datetime64[D]')

Business days in a period

getbizdays

Calendar.getbizdays(year: CountScalar, month: CountScalar = None) → float64
Calendar.getbizdays(year: Vector, month: CountScalar | Vector = None) → ndarray[tuple[Any, ...], dtype[float64]]
Calendar.getbizdays(year: CountScalar, month: Vector) → ndarray[tuple[Any, ...], dtype[float64]]

Business days in a whole year, or in one month.

Vector arguments must have equal lengths, or one of them must have length 1; otherwise ValueError.

Parameters:
  • year (int, numpy integer or float with a whole value, or a 1-D sequence of them) – Year

  • month (int, numpy integer or float with a whole value, or a 1-D sequence of them, optional) – Month, 1 to 12. The default None counts the whole year. Only the single value None means “whole year”; a missing value inside a vector, or any other missing scalar, gives NaN.

Returns:

The number of business days in each period, as float64, with NaN where year or month is missing. financial makes no difference. The whole period must lie inside the calendar range, otherwise DateOutOfRange: on ANBIMA, which ends on 2099-12-25, getbizdays(2099, 11) works while getbizdays(2099, 12) and getbizdays(2099) raise.

Return type:

numpy.float64 or numpy.ndarray

Raises:
  • DateOutOfRange – A period is not fully inside startdate..enddate; its positions attribute gives the index of every bad element.

  • ValueError – A year or month that is not a whole number, a month outside 1 to 12, or vector lengths that do not match, when neither is 1.

Examples:

>>> cal.getbizdays(2024)  # the whole year
np.float64(253.0)
>>> cal.getbizdays(2024, 2)
np.float64(19.0)
>>> cal.getbizdays([2024, 2024], [1, 2])
array([22., 19.])
>>> cal.getbizdays(2024, [1, None])
array([22., nan])

The whole period must lie inside the calendar range. ANBIMA ends on 2099-12-25, so November 2099 works and the year 2099 does not:

>>> cal.getbizdays(2099, 11)
np.float64(19.0)
>>> try:
...     cal.getbizdays(2099)
... except DateOutOfRange as e:
...     print(e.positions)
[0]