View Raw SPL
/****************************************************************************
*                                                                           *
*   DATEDURATION.SPL Copyright 2024 (C) DSP Development Corporation         *
*                                                                           *
*   Author:          Randy Race                                             *
*                                                                           *
*   Synopsis:        Calculates date difference in seconds                  *
*                                                                           *
*   Revisions:       10 Nov 2024     RRR     Creation                       *
*                                                                           *
****************************************************************************/


#if @HELP_DATEDURATION

    DATEDURATION

    Purpose: Calculates the difference of date series in seconds.

    Syntax:  DATEDURATION(date1, date2)

               date1 - A series of integer Julian date values,
                       the end date.

               date2 - Optional. A series of integer Julian date
                       values, the start date. Defaults to an empty
                       series.


    Returns: A series, the elapsed duration in seconds.

             If only one date series is specified, the durations are computed
             on the two point difference of each date value.

    Example:
             W1: ymd2date(2010, 11, 12)
             W2: ymd2date(2020, 10, 20)
             W3: dateduration(w2, w1)
             W4: dateoffset(w1, days:seconds2days(w3))

             W1 contains the date:

              11-12-2010

             W2 contains the date:

              10-20-2020

             W3 computes difference between the two date series in seconds,
             The duration is 313632000 seconds.

             W4 recovers the end date in W2 by adding to W3 the offset in
             seconds to the start date in W1. The seconds offset is converted
             to days to produce an input suitable to DATEOFFSET.

    Example:
             W1: ymd2date(2010, 11, 12)
             W2: ymd2date(2020, 10, 20)
             W3: dateduration(w1, w2)
             W4: dateoffset(w2, days:seconds2days(w3))

             Same as the first example except the start and end dates are
             swapped. The result is a negative duration of -313632000 seconds.

             W4 recovers the earlier end date in W1 by adding the
             negative seconds offset in W3 to the later start date in W2.

    Example:
             W1: gnorm(10, days2seconds(3))
             W2: col(getdt(w1), 1)
             W3: dateduration(w2)
             W4: seconds2days(w3)

             W1 contains 10 random samples with a time spacing of 3 days
             between samples.

             W2 computes the date values for each sample in W1.

             Because only one date series input was given, W3 computes
             the two point date difference in seconds between subsequent
             samples of W2. The result is 259200 seconds.

             W4 displays the time differences contained in W3 in days. The
             result is 3 days, matching the time spacing of W1.

    Remarks:
             DATEDURATION computes the duration between two date series
             with the result in seconds.

             If only one date series is provided, the two point period
             difference between subsequent date values is computed.

             A date duration is measured in seconds.

             A date period is measured in years, months and days.

             See DATEPERIOD to compute the date period in years, months
             and days.

    See Also:
             DATEPERIOD
             DATEOFFSET
             DTDIFF
             DTDURATION
             GETDT
             TIMEDURATION
             YMD2DATE
#endif


/* date difference in seconds */
dateduration(d1, d2)
{
        local days, seconds, usediff = FALSE;

        if (argc < 2)
        {
                if (argc < 1)
                {
                        error(sprintf("%s - input date series required", __FUNC__));
                }

                usediff = TRUE;
        }

        if (usediff)
        {
                /* two point difference in days */
                days = diff({d1});
        }
        else
        {
                /* difference between in days */
                days = {d1} - {d2};
        }

        /* convert to seconds */
        seconds = days * 86400;

        setvunits(seconds, "s");

        settable(seconds);

        return(seconds);
}