View Raw SPL
/****************************************************************************
*                                                                           *
*   TIMEOFFSET.SPL Copyright 2024 (C) DSP Development Corporation           *
*                                                                           *
*   Author:        Randy Race                                               *
*                                                                           *
*   Synopsis:      Add or subtract hours, minutes, seconds to time value    *
*                                                                           *
*   Revisions:     10 Nov 2024     RRR     Creation                         *
*                                                                           *
****************************************************************************/


#if @HELP_TIMEOFFSET

    TIMEOFFSET

    Purpose: Adds or subtracts hours, minutes and seconds to a time series.

    Syntax:  TIMEOFFSET(date, hours, minutes, seconds)

                  time - A TOD time series. Defaults to the current time.

                 hours - A scalar or series, the hours values. Defaults to 0.

               minutes - A scalar or series, the minutes values. Defaults to 0.

               seconds - A scalar or series, the seconds values. Defaults to 0.

    Returns: A TOD time series.

    Example:
             W1: hms2time(10, 1, 1)
             W2: timeoffset(w1, 1, 1, 1)

             W1 contains the time series:

                10:01:01

             W2 adds 1 hour, 1 minute and 1 second to the time in W1. The
             resulting time is:

               11:02:02

    Example:
             W1: hms2time(10, 1, 1)
             W2: timeoffset(w1, 1, 1, 1)
             W3: timeoffset(w2, -1, -1, -1)

             Same as above except W3 removes the offset in W2 to return
             the same time as in W1:

               10:01:01

    Example:
             W1: grand(3, 1000);settime(w0, "12:00:00")
             W2: col(getdt(w1), 2)
             W3: timeoffset(w2, minutes:1..3, hours:-3)
             W4: w3;setvunits("s");

             W1 generates a 3 point random series with a spacing between
             samples of 1000 seconds. The start time is set to 12:00:00.

             W2 obtains the time values for each sample of W1. W2 contains
             the time values:

               12:00:00
               12:16:40
               12:33:20

             W3 adds 1 minute to the first value, 2 minutes to the second
             value and 3 minutes to the last time value. It then
             subtracts 3 hours from each resulting date value. The time
             offset values are specified using the PARAMETER:VALUE syntax.
             The resulting time values in are:

              9:01:00
              9:18:40
              9:36:20

             W4 displays the time values in W3 as seconds. The seconds
             values are:

              32460
              33520
              34580

    Example:
             W1: grand(3, 1000);settime(w0, "12:00:00")
             W2: col(getdt(w1), 2)
             W3: timeoffset(w2, minutes:1..3, hours:-3)
             W4: timeperiod(w2, w3)
             W5: timeoffset(w3, w4)
             W6: w2 == w5

             Same as above except W4 computes the period in hours, minutes,
             and seconds between the time values in W2 and the time values in
             W3. The difference is 2 hour and 59 minutes for the first value,
             2 hours and 58 minutes for the second value and 2 hours 57
             minutes for the last value.

             W5 adds the offset values in W4 to the time values in W3.
             The resulting time values are the same as the original
             values in W2.

             W6 compares the time values of W2 and W5, verifying the values
             are identical.

    Remarks:
             TIMEOFFSET adds or subtracts hours, minutes and seconds from
             a time of day or TOD time series.

             An individual value of a TOD time series is the number of
             seconds since midnight. The fractional part represents
             fractional seconds to nanosecond precision.

             The offset values can be specified using the PARAMETER:VALUE
             syntax. For example:

               timeoffset(timedata, minutes:3, seconds:5)

             adds 3 minutes and 5 seconds to the time series TIMEDATA.

             The offset values are always added in hours, minutes, seconds
             order.

             Because TIMEOFFSET operates on purely TOD time series,
             the resulting values can be negative or rollover to exceed
             24 hours.

    See Also:
             DATEOFFSET
             DTDURATION
             DTOFFSET
             DTPERIOD
             GETDT
#endif



/* add offset to TOD time */
timeoffset(time = gettime(13), hours = 0, minutes = 0, seconds = 0)
{
        local newtime, timeoff;

        /* parse args */
        (time, hours, minutes, seconds) = timeoffset_parse_args(argc, time, hours, minutes, seconds);

        timeoff = hms2time(hours, minutes, seconds);

        newtime = time + timeoff;

        if (any((newtime - int(newtime)) % 1))
        {
                setvunits(newtime, "Real Time", -1);
        }
        else
        {
                setvunits(newtime, "Time", -1);
        }

        return(newtime);
}


/* parse args */
timeoffset_parse_args(nargs, time, hours, minutes, seconds)
{
        local h, m, s;

        h = hours;
        m = minutes;
        s = seconds;

        if (nargs < 2)
        {
                error(sprintf("%s - time and offset values required", __CALLER__));
        }
        else if (istime(time))
        {
                if (nargs == 2)
                {
                        /* time, {h, m, s} */
                        if (numcols(hours) > 1 && numcols(hours) <= 3)
                        {
                                try
                                {
                                        h = col(hours, 1);
                                        m = col(hours, 2);
                                        s = col(hours, 3);
                                }
                                catch
                                {
                                }
                        }
                        else
                        {
                                h = hours;
                        }
                }
        }

        return(time, h, m, s);
}