internals.dates
Dates: ss.date, an array of them (ss.DateArray), and calendar durations (datedur)
They give every module one way to work with calendar time, in calendar dates or in decimal years.
Used with: agents and compartments; declared and coded modules
Classes
| Name | Description |
|---|---|
| DateArray | Lightweight wrapper for an array of dates |
| date | Define a point in time, based on pd.Timestamp |
| datedur | A calendar duration, e.g. datedur(months=1): a thin wrapper of pd.DateOffset, used inside Starsim (as ss.dates.datedur) |
DateArray
internals.dates.DateArray()Lightweight wrapper for an array of dates
It exists so that a time vector, of dates or of durations, can be plotted and compared as one.
Attributes
| Name | Description |
|---|---|
| is_float | Whether the array holds plain numbers (False if it is empty) |
| subdaily | Check if the array has sub-daily timesteps |
| years | Represent the dates as floating point years |
Methods
| Name | Description |
|---|---|
| days_since | Exact (elapsed) number of days between each date and start, as an array of floats |
| to_array | Force conversion to an array |
| to_date | Convert to ss.date |
| to_float | Convert to a float, returning a new DateArray unless inplace=True |
| to_human | Return the most human-friendly (i.e. plotting-friendly) version of the dates, |
days_since
internals.dates.DateArray.days_since(start)Exact (elapsed) number of days between each date and start, as an array of floats
The same as dates - start (which gives ss.days), but as plain numbers, all at once.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| start | ss.date/str |
the date to count from | required |
Example
dates = ss.DateArray(['2000-01-01', '2000-02-01', '2000-03-01'])
dates.days_since('2000-01-01') # Returns array([ 0., 31., 60.])to_array
internals.dates.DateArray.to_array(*args, **kwargs)Force conversion to an array
to_date
internals.dates.DateArray.to_date(inplace=False, day_round=None, die=True)Convert to ss.date
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| inplace | bool |
whether to modify in place | False |
| day_round | bool |
whether to round dates to the nearest day (otherwise, keep timestamp); if None, round if and only if the span of the first timestep is at least one day | None |
| die | bool |
if False, then fall back to float if conversion to date fails (e.g. year 0) | True |
to_float
internals.dates.DateArray.to_float(inplace=False, to_numpy=False)Convert to a float, returning a new DateArray unless inplace=True
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| inplace | bool |
whether to change this array rather than return a new one | False |
| to_numpy | bool |
whether to return a NumPy array rather than a DateArray |
False |
to_human
internals.dates.DateArray.to_human()Return the most human-friendly (i.e. plotting-friendly) version of the dates, i.e. ss.date if possible, float otherwise
date
internals.dates.date()Define a point in time, based on pd.Timestamp
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| date | int / float / str / datetime |
Any type of date input (ints and floats will be interpreted as years) | |
| allow_zero | bool |
if True, allow a year 0 by creating a duration (ss.years) instead; if False, raise an exception; if None, give a warning | |
| kwargs | dict |
passed to pd.Timestamp() |
Examples
ss.date(2020) # Returns <2020-01-01>
ss.date(year=2020) # Returns <2020-01-01>
ss.date(year=2024.75) # Returns <2024-10-01>
ss.date('2024-04-04') # Returns <2024-04-04>
ss.date('2024-05') # Returns <2024-05-01>; ss.date('2024.5') is an error (May, or the middle of the year?), and ss.date(2024.5) is <2024-07-02>
ss.date(year=2024, month=4, day=4) # Returns <2024-04-04>Attributes
| Name | Description |
|---|---|
| years | Return the date as a number of years |
Methods
| Name | Description |
|---|---|
| arange | Construct an array of dates |
| disp | Show the full object |
| from_array | Convert an array of float years into an array of date instances |
| from_year | Convert an int or float year to a date. |
| replace | Returns a new ss.date(); pd.Timestamp is immutable |
| round | Round to a given interval (by default a day) |
| subdaily | Check if a subdaily timestep is used |
| to_json | Returns a JSON representation of the date |
| to_pandas | Convert to a standard pd.Timestamp instance |
| to_year | Convert a date to a floating-point year |
arange
internals.dates.date.arange(
start,
stop,
step=1.0,
inclusive=True,
day_round=None,
allow_zero=True,
)Construct an array of dates
Functions similarly to np.arange, but returns date objects
Example usage:
date.arange(2020, 2025) array([<2020-01-01>, <2021-01-01>, <2022-01-01>, <2023-01-01>, <2024-01-01>, <2025-01-01>], dtype=object)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| start | float / ss.date / ss.Duration |
Lower bound - can be a date or a numerical year | required |
| stop | float / ss.date / ss.Duration |
Upper bound - can be a date or a numerical year | required |
| step | float / ss.Duration |
Assumes 1 calendar year steps by default | 1.0 |
| inclusive | bool |
Whether to include “stop” in the output | True |
| day_round | bool |
Whether to round to the nearest day (by default, True if step > 1 day) | None |
| allow_zero | bool |
if True, allow a year 0 by creating a duration (ss.years) instead; if False, raise an exception; if None, give a warning | True |
Returns
| Name | Type | Description |
|---|---|---|
| An array of date instances |
disp
internals.dates.date.disp(**kwargs)Show the full object
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| **kwargs | dict |
passed to sc.pr() |
from_array
internals.dates.date.from_array(
array,
day_round=True,
allow_zero=True,
date_type=None,
)Convert an array of float years into an array of date instances
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| array | array |
An array of float years | required |
| day_round | bool |
Whether to round to the nearest day | True |
| allow_zero | bool |
if True, allow a year 0 by creating a duration (ss.years) instead; if False, raise an exception; if None, give a warning | True |
| date_type | type |
Optionally convert to a class other than ss.date (e.g. ss.years) |
None |
Returns
| Name | Type | Description |
|---|---|---|
| An array of date instances |
from_year
internals.dates.date.from_year(year, day_round=True, allow_zero=None)Convert an int or float year to a date.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| year | float |
the year to round | required |
| day_round | bool |
whether to round to the nearest day | True |
| allow_zero | bool |
whether to allow year 0 (if so, return ss.years instead) | None |
Examples
ss.date.from_year(2020) # Returns <2020-01-01>
ss.date.from_year(2024.75) # Returns <2024-10-01>replace
internals.dates.date.replace(*args, **kwargs)Returns a new ss.date(); pd.Timestamp is immutable
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| *args | list |
passed to pd.Timestamp.replace() |
|
| **kwargs | dict |
passed to pd.Timestamp.replace(), e.g. year=2030 |
round
internals.dates.date.round(to='d')Round to a given interval (by default a day)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| to | str |
the interval, as pd.Timestamp.round() reads it, e.g. ‘h’ |
'd' |
subdaily
internals.dates.date.subdaily(years)Check if a subdaily timestep is used
A date has no concept of a timestep, but add this as a convenience method since this is required by other methods (e.g. ss.date.arange()).
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| years | float |
the timestep, in years | required |
to_json
internals.dates.date.to_json()Returns a JSON representation of the date
to_pandas
internals.dates.date.to_pandas()Convert to a standard pd.Timestamp instance
to_year
internals.dates.date.to_year()Convert a date to a floating-point year
Examples
ss.date('2020-01-01').to_year() # Returns 2020.0
ss.date('2024-10-01').to_year() # Returns 2024.7486datedur
internals.dates.datedur(value=None, **kwargs)A calendar duration, e.g. datedur(months=1): a thin wrapper of pd.DateOffset, used inside Starsim (as ss.dates.datedur)
Users write ss.months(1) or ss.years(1): a whole number of months or years added to a date is already a calendar offset, so dt=ss.months(1) steps a sim by calendar months; a datedur is what the timeline steps by.
Added to a date, it follows the calendar, so a month from 31 January is the end of February and a year from 1 March 2020 is 1 March 2021. It takes whole numbers of years, months, weeks, and days (as keywords), or one of: a pd.DateOffset, a dateutil.relativedelta, a number of years, or a duration in one of these units (e.g. ss.days(7)). As a number (.years, .days, or divided by another duration) it is approximate, as other durations are: a year is 365 days, and a month a twelfth of a year. The time between two dates (date - date) is ss.days, not a datedur.
Examples
ss.date('2020-01-31') + datedur(months=1) # 2020-02-29
datedur(years=1)/datedur(months=1) # 12Attributes
| Name | Description |
|---|---|
| days | The approximate number of days |
| kwds | The number of each calendar unit, e.g. dict(months=1) |
| months | The approximate number of months |
| weeks | The approximate number of weeks |
| years | The approximate number of years, e.g. datedur(months=6).years is 0.5 |
Methods
| Name | Description |
|---|---|
| replace | Return an ss.Duration with the supplied value; see TimePar.replace() |
| to | As a plain duration in a unit (e.g. ‘year’ or ss.years), approximately, as other durations are, e.g. datedur(months=6).to(‘years’) is ss.years(0.5) |
| to_dur | As a plain duration, in the finest unit it has, e.g. datedur(years=1, days=10).to_dur() = ss.days(375) |
replace
internals.dates.datedur.replace(value)Return an ss.Duration with the supplied value; see TimePar.replace()
A datedur stores a date offset rather than a number, so the finest unit it was given in is used, e.g. datedur(days=10).replace(20) is ss.days(20).
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| value | float |
the new value | required |
to
internals.dates.datedur.to(unit)As a plain duration in a unit (e.g. ‘year’ or ss.years), approximately, as other durations are, e.g. datedur(months=6).to(‘years’) is ss.years(0.5)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| unit | str / type |
the unit, e.g. ‘year’ or ss.years |
required |
to_dur
internals.dates.datedur.to_dur()As a plain duration, in the finest unit it has, e.g. datedur(years=1, days=10).to_dur() = ss.days(375)