The chapter What is a time series? outlined that a sequence of time points can be interpreted as a list of non-overlapping time periods. This is represented by a TimeAxis object which is able to deal with fixed period time series as well as irregularly spaced time periods.

As the TimeAxis object is fundamental to a TimeSeries object, it needs to be created before the actual TimeSeries can be created. Its usage requires understanding Calendar and time.

There are several ways to create a TimeAxis and the right approach depends on the faced problem and available data.

Create a TimeAxis object

Fixed interval time axis

The simplest time axis is defined by a start time, a delta time value and the number of periods. This is also the most efficient one. To create the time axis we need a starting point t0, length of periods dt and how many periods n. The code below will create a time axis from the 01.01.2020 UTC until 08.01.2020 UTC with 24 hour periods.

from shyft.time_series import Calendar, TimeAxis, deltahours

# Create a utc-based calendar.
utc = Calendar()

t0 = utc.time(2020, 1, 1)
dt = deltahours(24) # alternatively: dt = Calendar.DAY
n = 7

ta = TimeAxis(start=t0, delta_t=dt, n=n)
# TimeAxis('2020-01-01T00:00:00Z', 86400s, 7)

Ireggular interval time axis

A time axis with irregularly spaced time periods can be created with the list of defined time points. The input time points are the starting point of each period, and we must add a last argument t_end to declare the end of the last period.

osl = sts.Calendar('Europe/Oslo')

t0 = osl.time(2021, 3, 1)
dt = sts.Calendar.MONTH
n = 5
ta_osl = sts.TimeAxis(calendar=osl, start=t0, delta_t=dt, n=n)


If the t_end is not supplied the time axis will assume that the last point in the list is the end of the last period.

Calendar time axis

The third option when creating a time axis is a calendar time axis, this will make the time axis aware of what a month is in a calendar setting, as well as daylight savings time.

ta_fixed = sts.TimeAxis(t0, dt, n)
# TimeAxis('2021-03-28T20:00:00Z', 3600s, 5)

for t_osl, t_fix in zip(ta_osl.time_points, ta_fixed.time_points):
    print(f'{osl.to_string(int(t_osl))}  |  {osl.to_string(int(t_fix))}')

And we can compare this with a fixed time axis

# 2021-05-01T00:00:00+02  |  2021-04-30T01:00:00+02
# 2021-06-01T00:00:00+02  |  2021-05-30T01:00:00+02
# 2021-07-01T00:00:00+02  |  2021-06-29T01:00:00+02
# 2021-08-01T00:00:00+02  |  2021-07-29T01:00:00+02

total_period = osl_ta.total_period()
# [2021-02-28T23:00:00Z,2021-07-31T22:00:00Z>

time_points = osl_ta.time_points
# array([1614553200, 1617228000, 1619820000, 1622498400, 1625090400,
#        1627768800])

Here we see that the calendar time axis (first column) always start the first of every calendar month at the start of the day, while in the fixed time axis it naively goes 2592000 seconds (Calendar.MONTH) forward.

A few helpful functions

A few helpful functions that helps us explore a given time axis.

total_period() returns a UtcPeriod that spans the total period of the time axis.

total_period = osl_ta.total_period()
# [2021-02-28T23:00:00Z,2021-07-31T22:00:00Z>

time_points returns an numpy.array with each starting point per period as well as the end of the last period.

time_points = osl_ta.time_points
# array([1614553200, 1617228000, 1619820000, 1622498400, 1625090400,
#        1627768800])


time_points returns time points in second resolution, as of now we need to use time_points_double to get sub-second resolution

size() returns the number of periods in the time axis.

size_ta = osl_ta.size()
# 5