sc_datetime
Time/date utilities.
Highlights
sc.tic()/sc.toc()/sc.timer(): simple methods for timing durationssc.readdate(): convert strings to dates using common formatssc.daterange(): create a list of datessc.datedelta(): perform calculations on date strings
Classes
| Name | Description |
|---|---|
| timer | Simple timer class. Note: sc.timer() and sc.Timer() are aliases. |
timer
sc_datetime.timer(
label=None,
auto=False,
start=True,
unit='auto',
verbose=None,
**kwargs,
)Simple timer class. Note: sc.timer() and sc.Timer() are aliases.
This wraps sc.tic() and sc.toc() with the formatting arguments and the start time (at construction).
Use this in a with block to automatically print elapsed time when the block finishes.
By default, output is displayed in seconds. You can change this with the unit argument, which can be a string or a float:
- 'hr' or 3600
- 'min' or 60
- 's' or 1 (default)
- 'ms' or 1e-3
- 'us' or 1e-6
- 'ns' or 1e-9
- 'auto' to choose an appropriate unit
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| label | str | label identifying this timer | None |
| auto | bool | whether to automatically increment the label | False |
| start | bool | whether to start timing from object creation (else, call timer.tic() explicitly) |
True |
| unit | str / float | the unit of time to display; see options above | 'auto' |
| verbose | bool | whether to print output on each timing | None |
| kwargs | dict | passed to sc.toc() when invoked |
{} |
Example making repeated calls to the same timer, using auto to keep track:
>>> T = sc.timer(auto=True)
>>> T.toc()
(0): 2.63 s
>>> T.toc()
(1): 5.00 sExample wrapping code using with-as:
>>> with sc.timer('mylabel'):
>>> sc.timedsleep(0.5)Example using a timer to collect data, using timer.tt() as an alias for sc.toctic() to reset the time:
T = sc.timer(verbose=False)
for key in 'abcde':
sc.timedsleep(np.random.rand())
T.tt(key)
print(T.timings)Implementation based on https://preshing.com/20110924/timing-your-code-using-pythons-with-statement/
- New in version 1.3.0:
sc.timer()alias, and allowing the label as first argument - New in version 1.3.2:
toc()passes label correctly;tt()method;autoargument - New in version 2.0.0:
plot()method;total()method;indivtimingsandcumtimingsproperties - New in version 2.1.0:
totalas property instead of method; updated repr; added disp() method - New in version 3.0.0:
unitargument;verboseargument;sum, min, max, mean, stdmethods;rawtimingsproperty - New in version 3.1.0: Timers can be combined by addition, including
sum() - New in version 3.1.5:
T.timingsis now ansc.objdict()instead of ansc.odict() - New in version 3.2.2:
sc.timer()can be used as a function decorator - New in version 3.2.5:
.stringattribute (e.g. ‘3.25 s’) - New in version 3.3.0:
toctotal()method
Attributes
| Name | Description |
|---|---|
| cumtimings | Compute the cumulative time for each timing |
| indivtimings | Compute the individual time between each timing |
| rawtimings | Return an array of timings |
| total | Calculate total time |
Methods
| Name | Description |
|---|---|
| disp | Display the full representation of the object |
| max | Maximum of timings |
| mean | Mean of timings |
| min | Minimum of timings |
| plot | Create a plot of Timer.timings |
| start | Alias for sc.tic() |
| std | Standard deviation of timings |
| stop | Alias for sc.toc() |
| sum | Sum of timings; similar to timer.total |
| tic | Set start time |
| toc | Print elapsed time; see sc.toc() for keyword arguments |
| tocout | Alias for sc.toc() with output=True |
| toctic | Like toc, but reset time between timings |
| toctotal | Like toc, but time from the first tic rather than the most recent one |
| tt | Alias for sc.toctic() |
| tto | Alias for sc.toctic() with output=True |
disp
sc_datetime.timer.disp()Display the full representation of the object
max
sc_datetime.timer.max()Maximum of timings
New in version 3.0.0.
mean
sc_datetime.timer.mean()Mean of timings
New in version 3.0.0.
min
sc_datetime.timer.min()Minimum of timings
New in version 3.0.0.
plot
sc_datetime.timer.plot(fig=None, figkwargs=None, grid=True, **kwargs)Create a plot of Timer.timings
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| cumulative | bool | how the timings will be presented, individual or cumulative | required |
| fig | fig |
an existing figure to draw the plot in | None |
| figkwargs | dict | passed to plt.figure() |
None |
| grid | bool | whether to show a grid | True |
| kwargs | dict | passed to plt.bar() |
{} |
New in version 2.0.0.
start
sc_datetime.timer.start()Alias for sc.tic()
std
sc_datetime.timer.std()Standard deviation of timings
New in version 3.0.0.
stop
sc_datetime.timer.stop(*args, verbose=False, **kwargs)Alias for sc.toc()
sum
sc_datetime.timer.sum()Sum of timings; similar to timer.total
New in version 3.0.0.
tic
sc_datetime.timer.tic()Set start time
toc
sc_datetime.timer.toc(label=None, **kwargs)Print elapsed time; see sc.toc() for keyword arguments
tocout
sc_datetime.timer.tocout(label=None, output=True, **kwargs)Alias for sc.toc() with output=True
toctic
sc_datetime.timer.toctic(*args, reset=True, **kwargs)Like toc, but reset time between timings
toctotal
sc_datetime.timer.toctotal(label='Total', **kwargs)Like toc, but time from the first tic rather than the most recent one
Example:
T = sc.timer()
sc.timedsleep(0.1)
T.toctic()
sc.timedsleep(0.1)
T.toctic()
T.toctotal() # Time since the timer was created, not since the last ticNew in version 3.3.0.
tt
sc_datetime.timer.tt(*args, **kwargs)Alias for sc.toctic()
tto
sc_datetime.timer.tto(*args, output=True, **kwargs)Alias for sc.toctic() with output=True
Functions
| Name | Description |
|---|---|
| date | Convert any reasonable object – a string, integer, or datetime object, or |
| datedelta | Perform calculations on a date string (or date object), returning a string (or a date). |
| daterange | Return a list of dates from the start date to the end date. To convert a list |
| datetoyear | Convert a date to decimal year. |
| day | Convert a string, date/datetime object, or int to a day (int), the number of |
| daydiff | Convenience function to find the difference between two or more days. With |
| elapsedtimestr | Accepts a datetime object or a string in ISO 8601 format and returns a |
| getdate | Alias for converting a date object to a formatted string. |
| now | Get the current time as a datetime object, optionally in UTC time. |
| randsleep | Sleep for a nondeterminate period of time (useful for desynchronizing tasks) |
| readdate | Convenience function for loading a date from a string. If dateformat is None, |
| tic | With sc.toc(), a little pair of functions to calculate a time difference: |
| time | Get current time in seconds – alias to time.time() |
| timedsleep | Pause for the specified amount of time, taking into account how long other |
| toc | With sc.tic(), a little pair of functions to calculate a time difference. See |
| toctic | A convenience fuction for multiple timings. Can return the default output of |
| yeartodate | Convert a decimal year to a date |
date
sc_datetime.date(
obj=None,
*args,
start_date=None,
readformat=None,
to='date',
as_date=None,
outformat=None,
**kwargs,
)Convert any reasonable object – a string, integer, or datetime object, or list/array of any of those – to a date object (or string, pandas, or numpy date).
If the object is an integer, this is interpreted as follows:
- With readformat=‘posix’: treat as a POSIX timestamp, in seconds from 1970
- With readformat=‘ordinal’/‘matplotlib’: treat as an ordinal number of days from 1970 (Matplotlib default)
- With start_date provided: treat as a number of days from this date
Note: in this and other date functions, arguments work either with or without underscores (e.g. start_date or startdate)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| obj | str / int / date / datetime / list / array | the object to convert; if None, return current date | None |
| args | str / int / date / datetime | additional objects to convert | () |
| start_date | str / date / datetime | the starting date, if an integer is supplied | None |
| readformat | str / list | the format to read the date in; passed to sc.readdate() (NB: can also use “format” instead of “readformat”) |
None |
| to | str | the output format: ‘date’ (default), ‘datetime’, ‘str’ (or ‘string’), ‘pandas’, or ‘numpy’ | 'date' |
| as_date | bool | alternate method of choosing between output format of ‘date’ (True) or ‘str’ (False); if None, use “to” instead | None |
| outformat | str | the format to output the date in, if returning a string | None |
| kwargs | dict | only used for deprecated argument aliases | {} |
Returns
| Name | Type | Description |
|---|---|---|
| dates | date or list | either a single date object, or a list of them (matching input data type where possible) |
Examples:
sc.date('2020-04-05') # Returns datetime.date(2020, 4, 5)
sc.date([35,36,37], start_date='2020-01-01', to='str') # Returns ['2020-02-05', '2020-02-06', '2020-02-07']
sc.date(1923288822, readformat='posix') # Interpret as a POSIX timestamp- New in version 1.0.0.
- New in version 1.2.2: “readformat” argument; renamed “dateformat” to “outformat”
- New in version 2.0.0: support for
np.datetime64objects - New in version 3.0.0: added “to” argument, and support for
pd.Timestampandnp.datetime64output; allow None - New in version 3.1.0: allow “datetime” output
datedelta
sc_datetime.datedelta(
datestr=None,
days=0,
months=0,
years=0,
weeks=0,
dt1=None,
dt2=None,
as_date=None,
**kwargs,
)Perform calculations on a date string (or date object), returning a string (or a date). Wrapper to dateutil.relativedelta.relativedelta().
If datestr is None, then return the delta object rather than the new date.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| datestr | None / str / date / list | the starting date (typically a string); if None, return the relative delta | None |
| days | int | the number of days (positive or negative) to increment | 0 |
| months | int | as above | 0 |
| years | int / float | as above; if a float, converted to days (NB: fractional months and weeks are not supported) | 0 |
| weeks | int | as above | 0 |
| dt1, dt2 | dates |
if both provided, compute the difference between them | required |
| as_date | bool | if True, return a date object; otherwise, return as input type | None |
| kwargs | dict | passed to sc.date() |
{} |
Examples:
sc.datedelta('2021-07-07', 3) # Add 3 days
sc.datedelta('2021-07-07', days=-4) # Subtract 4 days
sc.datedelta('2021-07-07', weeks=4, months=-1, as_date=True) # Add 4 weeks but subtract a month, and return a dateobj
sc.datedelta(days=3) # Alias to du.relativedelta.relativedelta(days=3)
sc.datedelta(['2021-07-07', '2022-07-07'], months=1) # Increment multiple dates
sc.datedelta('2020-06-01', years=0.25) # Use a fractional number of years (to the nearest day)- New in version 3.0.0: operate on list of dates
- New in version 3.1.0: handle all date input formats
- New in version 3.2.0: handle fractional years
daterange
sc_datetime.daterange(
start_date=None,
end_date=None,
interval=None,
inclusive=True,
as_date=None,
readformat=None,
outformat=None,
**kwargs,
)Return a list of dates from the start date to the end date. To convert a list of days (as integers) to dates, use sc.date() instead.
Note: instead of an end date, can also pass one or more of days, months, weeks, or years, which will be added on to the start date via sc.datedelta().
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| start_date (int/str/date) | the starting date, in any format | required | |
| end_date (int/str/date) | the end date, in any format (see also kwargs below) | required | |
| interval (int/str/dict) | if an int, the number of days; if ‘week’, ‘month’, or ‘year’, one of those; if a dict, passed to dt.relativedelta() |
required | |
| inclusive (bool) | if True (default), return to end_date inclusive; otherwise, stop the day before | required | |
| as_date (bool) | if True, return a list of datetime.date objects; else, as input type (e.g. strings; note: you can also use “asdate” instead of “as_date”) |
required | |
| readformat (str) | passed to sc.date() |
required | |
| outformat (str) | passed to sc.date() |
required | |
| kwargs (dict) | optionally, use any valid argument to sc.datedelta() to create the end_date |
required |
Examples:
dates1 = sc.daterange('2020-03-01', '2020-04-04')
dates2 = sc.daterange('2020-03-01', '2022-05-01', interval=dict(months=2), asdate=True)
dates3 = sc.daterange('2020-03-01', weeks=5)- New in version 1.0.0.
- New in version 1.3.0: “interval” argument
- New in version 2.0.0:
sc.datedelta()arguments - New in version 3.0.0: preserve input type
datetoyear
sc_datetime.datetoyear(dateobj, dateformat=None, **kwargs)Convert a date to decimal year.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| dateobj | (date, str, pd.TimeStamp) |
The datetime instance to convert | required |
| dateformat | str | If dateobj is a string, the optional date conversion format to use | None |
Returns
| Name | Type | Description |
|---|---|---|
| Equivalent decimal year from date, or date from decial year |
Example:
sc.datetoyear('2010-07-01') # Returns approximately 2010.5
sc.datetoyear(2010.5) # Returns datetime.date(2010, 7, 2)By Luke Davis from https://stackoverflow.com/a/42424261, adapted by Romesh Abeysuriya.
- New in version 1.0.0.
- New in version 3.2.0: “reverse” argument
- New in version 3.2.1: “reverse” argument replaced by sc.yeartodate()
day
sc_datetime.day(obj, *args, start_date=None, **kwargs)Convert a string, date/datetime object, or int to a day (int), the number of days since the start day. See also sc.date() and `sc.daydiff()``. If a start day is not supplied, it returns the number of days into the current year.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| obj | (str, date, int, list, array) | convert any of these objects to a day relative to the start day | required |
| args | list | additional days | () |
| start_date | str or date | the start day; if none is supplied, return days since (supplied year)-01-01. | None |
Returns
| Name | Type | Description |
|---|---|---|
| days | int or list | the day(s) in simulation time (matching input data type where possible) |
Examples:
sc.day(sc.now()) # Returns how many days into the year we are
sc.day(['2021-01-21', '2024-04-04'], start_date='2022-02-22') # Days can be positive or negative- New in version 1.0.0.
- New in version 1.2.2: renamed “start_day” to “start_date”
daydiff
sc_datetime.daydiff(*args)Convenience function to find the difference between two or more days. With only one argument, calculate days since Jan. 1st.
Examples:
diff = sc.daydiff('2020-03-20', '2020-04-05') # Returns 16
diffs = sc.daydiff('2020-03-20', '2020-04-05', '2020-05-01') # Returns [16, 26]
doy = sc.daydiff('2022-03-20') # Returns 79, the number of days since 2022-01-01- New in version 1.0.0.
- New in version 3.0.0: Calculated relative days with one argument
- New in version 3.2.2: handle list as first argument
elapsedtimestr
sc_datetime.elapsedtimestr(pasttime, maxdays=5, minseconds=10, shortmonths=True)Accepts a datetime object or a string in ISO 8601 format and returns a human-readable string explaining when this time was.
The rules are as follows:
- If a time is within the last hour, return ‘XX minutes’
- If a time is within the last 24 hours, return ‘XX hours’
- If within the last 5 days, return ‘XX days’
- If in the same year, print the date without the year
- If in a different year, print the date with the whole year
These can be configured as options.
Examples:
yesterday = sc.datedelta(sc.now(), days=-1)
sc.elapsedtimestr(yesterday)getdate
sc_datetime.getdate(obj=None, astype='str', dateformat=None)Alias for converting a date object to a formatted string.
See also sc.now().
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| obj | datetime | the datetime object to convert | None |
| astype | str | what to return; choices are “str” (default), “dateobj”, “float” (full timestamp), “int” (timestamp to second precision) | 'str' |
| dateformat | str | if astype is 'str', use this output format |
None |
Examples:
sc.getdate() # Returns a string for the current date
sc.getdate(astype='float') # Convert today's time to a timestampnow
sc_datetime.now(
astype='dateobj',
timezone=None,
utc=False,
tostring=False,
dateformat=None,
)Get the current time as a datetime object, optionally in UTC time.
sc.now() is similar to sc.getdate(), but sc.now() returns a datetime object by default, while sc.getdate() returns a string by default.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| astype (str) | what to return; choices are “dateobj”, “str”, “float”; see sc.getdate() for more |
required | |
| timezone (str) | the timezone to set the itme to | required | |
| utc (bool) | whether the time is specified in UTC time | required | |
| dateformat (str) | if astype is 'str', use this output format |
required |
Examples:
sc.now() # Return current local time, e.g. 2019-03-14 15:09:26
sc.now(timezone='US/Pacific') # Return the time now in a specific timezone
sc.now(utc=True) # Return the time in UTC
sc.now(astype='str') # Return the current time as a string instead of a date object; use 'int' for seconds
sc.now(tostring=True) # Backwards-compatible alias for astype='str'
sc.now(dateformat='%Y-%b-%d') # Return a different date formatNew in version 1.3.0: made “astype” the first argument; removed “tostring” argument
randsleep
sc_datetime.randsleep(delay=1.0, var=1.0, low=None, high=None, seed=None)Sleep for a nondeterminate period of time (useful for desynchronizing tasks)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| delay | float / list | average duration in seconds to sleep for; if a pair of values, treat as low and high | 1.0 |
| var | float | how much variability to have (default, 1.0, i.e. from 0 to 2*interval) | 1.0 |
| low | float | optionally define lower bound of sleep | None |
| high | float | optionally define upper bound of sleep | None |
| seed | int | if provided, reset the random seed | None |
Examples:
sc.randsleep(1) # Sleep for 0-2 s (average 1.0)
sc.randsleep(2, 0.1) # Sleep for 1.8-2.2 s (average 2.0)
sc.randsleep([0.5, 1.5]) # Sleep for 0.5-1.5 s
sc.randsleeep(low=0.5, high=1.5) # DittoNew in version 2.0.0. New in version 3.0.0: “seed” argument
readdate
sc_datetime.readdate(
datestr=None,
*args,
dateformat=None,
return_defaults=False,
verbose=False,
)Convenience function for loading a date from a string. If dateformat is None, this function tries a list of standard date types. Note: in most cases sc.date() should be used instead.
By default, a numeric date is treated as a POSIX (Unix) timestamp. This can be changed with the dateformat argument, specifically:
- ‘posix’/None: treat as a POSIX timestamp, in seconds from 1970
- ‘ordinal’/‘matplotlib’: treat as an ordinal number of days from 1970 (Matplotlib default)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| datestr | (int, float, str or list) | the string containing the date, or the timestamp (in seconds), or a list of either | None |
| args | list | additional dates to convert | () |
| dateformat | str or list | the format for the date, if known; if ‘dmy’ or ‘mdy’, try as day-month-year or month-day-year formats; can also be a list of options | None |
| return_defaults | bool | don’t convert the date, just return the defaults | False |
| verbose | bool | return detailed error messages | False |
Returns
| Name | Type | Description |
|---|---|---|
| dateobj | datetime | a datetime object |
Examples:
dateobj = sc.readdate('2020-03-03') # Standard format, so works
dateobj = sc.readdate('04-03-2020', dateformat='dmy') # Date is ambiguous, so need to specify day-month-year order
dateobj = sc.readdate(1611661666) # Can read timestamps as well
dateobj = sc.readdate(16166, dateformat='ordinal') # Or ordinal numbers of days, as used by Matplotlib
dateobjs = sc.readdate(['2020-06', '2020-07'], dateformat='%Y-%m') # Can read custom date formats
dateobjs = sc.readdate('20200321', 1611661666) # Can mix and match formatstic
sc_datetime.tic()With sc.toc(), a little pair of functions to calculate a time difference:
Examples:
sc.tic()
slow_func()
sc.toc()
T = sc.tic()
slow_func2()
sc.toc(T, label='slow_func2')See also sc.timer().
time
sc_datetime.time()Get current time in seconds – alias to time.time()
See also sc.now() to return a datetime object, and sc.getdate() to return a string.
New in version 3.0.0.
timedsleep
sc_datetime.timedsleep(delay=None, start=None, verbose=False)Pause for the specified amount of time, taking into account how long other operations take.
This function is usually used in a loop; it works like time.sleep(), but subtracts time taken by the other operations in the loop so that each loop iteration takes exactly delay amount of time. Note: since time.sleep() has a minimum overhead (about 2e-4 seconds), below this duration, no pause will occur.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| delay | float | time, in seconds, to wait for | None |
| start | float | if provided, the start time | None |
| verbose | bool | whether to print details | False |
Examples:
# Example for a long(ish) computation
import numpy as np
for i in range(10):
sc.timedsleep('start') # Initialize
n = int(2*np.random.rand()*1e6) # Variable computation time
for j in range(n):
tmp = np.random.rand()
sc.timedsleep(1, verbose=True) # Wait for one second per iteration including computation time
# Example illustrating more accurate timing
import time
n = 1000
with sc.timer():
for i in range(n):
sc.timedsleep(1/n)
# Elapsed time: 1.01 s
with sc.timer():
for i in range(n):
time.sleep(1/n)
# Elapsed time: 1.21 sNew in version 3.0.0: “verbose” False by default; more accurate overhead calculation
toc
sc_datetime.toc(
start=None,
label=None,
baselabel=None,
sigfigs=None,
reset=False,
unit='s',
output=False,
verbose=None,
elapsed=None,
**kwargs,
)With sc.tic(), a little pair of functions to calculate a time difference. See also sc.timer().
By default, output is displayed in seconds. You can change this with the unit argument, which can be a string or a float:
- 'hr' or 3600
- 'min' or 60
- 's' or 1 (default)
- 'ms' or 1e-3
- 'us' or 1e-6
- 'ns' or 1e-9
- 'auto' to choose an appropriate unit
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| start | float | the starting time, as returned by e.g. sc.tic() |
None |
| label | str | optional label to add | None |
| baselabel | str | optional base label; default is “Elapsed time:” | None |
| sigfigs | int | number of significant figures for time estimate | None |
| reset | bool | reset the time; like calling sc.toctic() or sc.tic() again |
False |
| unit | str / float | the unit of time to display; see options above | 's' |
| output | bool | whether to return the output (otherwise print); if output=‘message’, then return the message string; if output=‘both’, then return both | False |
| verbose | bool | whether to print (true by default) | None |
| elapsed | float | use a pre-calculated elapsed time instead of recalculating (not recommneded) | None |
| kwargs | dict | not used; only for handling deprecations | {} |
Examples:
sc.tic()
slow_func()
sc.toc()
T = sc.tic()
slow_func2()
sc.toc(T, label='slow_func2')- New in version 1.3.0: new arguments
- New in version 3.0.0: “unit” argument
- New in version 3.2.1: renamed “doprint” to “verbose”
toctic
sc_datetime.toctic(returntic=False, returntoc=False, *args, **kwargs)A convenience fuction for multiple timings. Can return the default output of either sc.tic() or sc.toc() (default neither). Arguments are passed to sc.toc(). Equivalent to sc.toc(reset=True).
Example:
sc.tic()
slow_operation_1()
sc.toctic()
slow_operation_2()
sc.toc()New in version 1.0.0.
yeartodate
sc_datetime.yeartodate(year, as_date=True, **kwargs)Convert a decimal year to a date
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| year | (int, float) | The numerical year to convert to a DateTime | required |
| as_date | bool | If True (default), return an sc.date object, otherwise return a string |
True |
Returns
| Name | Type | Description |
|---|---|---|
An sc.date object (default) or string, depending on the as_date argument |
Example:
sc.yeartodate('2010-07-01') # Returns approximately 2010.5- New in version 3.2.1.