Time reference system
Time reference system Time reference system (TRS) is a local, regional or global system used to identify time. A time reference system defines a specific projection for forward and reverse mapping between a timestamp and its numeric representation. A common example that most users are familiar with is UTC time, which maps a timestamp, for example, (1 Jan 2019, 12 midnight (GMT) into a 64-bit integer value (1546300800000), which captures the number of milliseconds that have elapsed since 1 Jan 1970, 12 midnight (GMT). Generally speaking, the timestamp value is better suited for human readability, while the numeric representation is better suited for machine processing. In the time series library, a time series can be associated with a TRS. A TRS is composed of a: * Time tick that captures time granularity, for example 1 minute * Zoned date time that captures a start time, for example 1 Jan 2019, 12 midnight US Eastern Daylight Savings time (EDT). A timestamp is mapped into a numeric representation by computing the number of elapsed time ticks since the start time. A numeric representation is scaled by the granularity and shifted by the start time when it is mapped back to a timestamp. Note that this forward + reverse projection might lead to time loss. For instance, if the true time granularity of a time series is in seconds, then forward and reverse mapping of the time stamps 09:00:01 and 09:00:02 (to be read as hh:mm:ss) to a granularity of one minute would result in the time stamps 09:00:00 and 09:00:00 respectively. In this example, a time series, whose granularity is in seconds, is being mapped to minutes and thus the reverse mapping looses information. However, if the mapped granularity is higher than the granularity of the input time series (more specifically, if the time series granularity is an integral multiple of the mapped granularity) then the forward + reverse projection is guaranteed to be lossless. For example, mapping a time series, whose granularity is in minutes, to seconds and reverse projecting it to minutes would result in lossless reconstruction of the timestamps. Setting TRS When a time series is created, it is associated with a TRS (or None if no TRS is specified). If the TRS is None, then the numeric values cannot be mapped to timestamps. Note that TRS can only be set on a time series at construction time. The reason is that a time series by design is an immutable object. Immutability comes in handy when the library is used in multi-threaded environments or in distributed computing environments such as Apache Spark. While a TRS can be set only at construction time, it can be changed using the with_trs method as described in the next section. with_trs produces a new time series and thus has no impact on immutability. Let us consider a simple time series created from an in-memory list: values = [1.0, 2.0, 4.0] x = tspy.time_series(values) x This returns: TimeStamp: 0 Value: 1.0 TimeStamp: 1 Value: 2.0 TimeStamp: 2 Value: 4.0 At construction time, the time series can be associated with a TRS. Associating a TRS with a time series allows its numeric timestamps to be as per the time tick and offset/timezone. The following example shows 1 minute and 1 Jan 2019, 12 midnight (GMT): zdt = datetime.datetime(2019,1,1,0,0,0,0,tzinfo=datetime.timezone.utc) x_trs = tspy.time_series(data, granularity=datetime.timedelta(minutes=1), start_time=zdt) x_trs This returns: TimeStamp: 2019-01-01T00:00Z Value: 1.0 TimeStamp: 2019-01-01T00:01Z Value: 2.0 TimeStamp: 2019-01-01T00:02Z Value: 4.0 Here is another example where the numeric timestamps are reinterpreted with a time tick of one hour and offset/timezone as 1 Jan 2019, 12 midnight US Eastern Daylight Savings time (EDT). tz_edt = datetime.timezone.edt zdt = datetime.datetime(2019,1,1,0,0,0,0,tzinfo=tz_edt) x_trs = tspy.time_series(data, granularity=datetime.timedelta(hours=1), start_time=zdt) x_trs This returns: TimeStamp: 2019-01-01T00:00-04:00 Value: 1.0 TimeStamp: 2019-01-01T00:01-04:00 Value: 2.0 TimeStamp: 2019-01-01T00:02-04:00 Value: 4.0 Note that the timestamps now indicate an offset of -4 hours from GMT (EDT timezone) and captures the time tick of one hour. Also note that setting a TRS does NOT change the numeric timestamps - it only specifies a way of interpreting numeric timestamps. x_trs.print(human_readable=False) This returns: TimeStamp: 0 Value: 1.0 TimeStamp: 1 Value: 2.0 TimeStamp: 2 Value: 4.0 Changing TRS You can change the TRS associated with a time series using the with_trs function. Note that this function will throw an exception if the input time series is not associated with a TRS (if TRS is None). Using with_trs changes the numeric timestamps. The following code sample shows TRS set at contructions time without using with_trs: 1546300800 is the epoch time in seconds for 1 Jan 2019, 12 midnight GMT zdt1 = datetime.datetime(1970,1,1,0,0,0,0,tzinfo=datetime.timezone.utc) y = tspy.observations.of(tspy.observation(1546300800, 1.0),tspy.observation(1546300860, 2.0), tspy.observation(1546300920, 4.0)).to_time_series(granularity=datetime.timedelta(seconds=1), start_time=zdt1) y.print() y.print(human_readable=False) This returns: TimeStamp: 2019-01-01T00:00Z Value: 1.0 TimeStamp: 2019-01-01T00:01Z Value: 2.0 TimeStamp: 2019-01-01T00:02Z Value: 4.0 TRS has been set during construction time - no changes to