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


#if @HELP_DATEPERIOD

    DATEPERIOD

    Purpose: Calculates the difference of date series in years, months and
             days.

    Syntax:  DATEPERIOD(date1, date2)

             (y, m, d) = DATEPERIOD(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: The elapsed period as an N x 3 series of years, months and
             days.

             (y, m, d) = DATEPERIOD(date1, date2)

             returns the values in separate variables.
             
             If only one date series is specified, the periods are computed
             on the two point difference of each date value.

    Example:
             W1: ymd2date(2010, 11, 12)
             W2: ymd2date(2020, 10, 20)
             W3: dateperiod(w2, w1)
             W4: dateoffset(w1, 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 period is 9 years, 11 months and 8 days.

             W4 recovers the end date in W2 by adding the offset in W3 to
             the start date in W1.

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

             Same as the first example except the start and end dates
             are swapped. The result is a negative period, -9 years,
             -11 months and -8 days.

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

    Remarks:
             DATEPERIOD computes the difference between two date series
             with the result in periods of years, months and days.

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

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

             A date duration is measured in seconds.

             See DATEDURATION to compute the time difference in seconds.

    See Also:
             DATEDURATION
             DATEOFFSET
             DTDIFF
             DTDURATION
             TIMEPERIOD
             YMD2DATE
#endif


/* date difference in years, months, days */
dateperiod(d1, d2)
{
        local y, m, d, delta_d, ymd, usediff = FALSE;

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

                usediff = TRUE;
        }

        if (usediff)
        {
                /* two point difference */
                (y, m, d) = dtdifference({d1}, {0}, {}, {});
        }
        else
        {
                /* difference between */
                (y, m, d) = dtdifference({d1}, {0}, {d2}, {0});
        }

        if (outargc > 1)
        {
                return(y, m, d);
        }
        else
        {
                ymd = ravel(y, m, d);

                settable(ymd);

                return(ymd);
        }
}