sc_datetime

sc_datetime

Time/date utilities.

Highlights

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 s

Example 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; auto argument
  • New in version 2.0.0: plot() method; total() method; indivtimings and cumtimings properties
  • New in version 2.1.0: total as property instead of method; updated repr; added disp() method
  • New in version 3.0.0: unit argument; verbose argument; sum, min, max, mean, std methods; rawtimings property
  • New in version 3.1.0: Timers can be combined by addition, including sum()
  • New in version 3.1.5: T.timings is now an sc.objdict() instead of an sc.odict()
  • New in version 3.2.2: sc.timer() can be used as a function decorator
  • New in version 3.2.5: .string attribute (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 tic

New 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.datetime64 objects
  • New in version 3.0.0: added “to” argument, and support for pd.Timestamp and np.datetime64 output; 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 timestamp

now

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 format

New 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) # Ditto

New 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 formats

tic

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 s

New 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.