View Raw SPL
/****************************************************************************
* *
* DATEOFFSET.SPL Copyright 2024 (C) DSP Development Corporation *
* *
* Author: Randy Race *
* *
* Synopsis: Add or subtract years, months, days *
* *
* Revisions: 10 Nov 2024 RRR Creation *
* *
****************************************************************************/
#if @HELP_DATEOFFSET
DATEOFFSET
Purpose: Adds or subtracts years, months, days to a Julian date.
Syntax: DATEOFFSET(date, years, months, days)
date - A Julian date series.
years - A scalar or series, the year values. Defaults to 0.
months - A scalar or series, the month values. Defaults to 0.
days - A scalar or series, the day values. Defaults to 0.
Returns: A date series.
Example:
W1: ymd2date(2030, 1, 1)
W2: dateoffset(w1, 1, 1, 1)
W1 contains the date series:
1-1-2030
W2 adds 1 year, 1 month and 1 day to the date in W1. The
resulting date is:
2-2-2031
Example:
W1: ymd2date(2030, 1, 1)
W2: dateoffset(w1, 1, 1, 1)
W3: dateoffset(w2, -1, -1, -1)
Same as above except W3 removes the offset in W2 to return
the same date as in W1:
1-1-2030
Example:
W1: grand(3, 100000);setdate(w0, "1-1-2030")
W2: col(getdt(w1), 1)
W3: dateoffset(w2, months:1..3, days:-3)
W1 generates a 3 point random series with a spacing between
samples of 100000 seconds. The start date is set to 1-1-2030.
W2 obtains the date values for each sample of W1. W2 contains
the date values:
1-01-2030
1-02-2030
1-03-2030
W3 adds 1 month to the first value, 2 months to the second value
and 3 months to the last date value and then then subtracts
3 days from each resulting date value. The date offset values are
specified using the PARAMETER:VALUE syntax. The resulting date
values are:
1-29-2030
2-27-2030
3-21-2030
Example:
W1: grand(3, 100000);setdate(w0, "1-1-2030")
W2: col(getdt(w1), 1)
W3: dateoffset(w2, months:-3, days:1..3)
W4: dateperiod(w2, w3)
W5: dateoffset(w3, w4)
W6: w2 == w5
Same as above except W4 computes the period in years, months,
and days between the date values in W2 and the date values in
W3. The difference is 2 month and 30 days for the first value,
2 months and 29 days for the second value and 2 months 28 days
for the last value.
W5 adds the offset values in W4 to the date values in W3.
The resulting date values are the same as the original
values in W2. In this case, subtracting 3 months and adding 1,
2 and 3 days to the date values in W2 is the same as subtracting
2 months and subtracting 30, 29, and 28 days to the date values
in W2,
W6 compares the date values of W2 and W5, verifying the values
are identical.
Remarks:
DATEOFFSET adds or subtracts years, months, days and hours
from a date series.
The offset values can be specified using the PARAMETER:VALUE
syntax. For example:
dateoffset(dt, months:3, days:5)
adds 3 months and 5 days to the date series DT.
The offset values are always added in years, months, days order.
See Also:
DTDURATION
DTOFFSET
DTPERIOD
GETDT
TIMEOFFSET
#endif
/* add offset to julian date */
dateoffset(date = getdate(), years = 0, months = 0, days = 0)
{
/* parse args */
(date, years, months, days) = dateoffset_parse_args(argc, date, years, months, days);
/* internal function */
date = juloffset({date}, {years}, {months}, {days});
return(date);
}
/* parse args */
dateoffset_parse_args(nargs, date, years, months, days)
{
local y, m, d;
y = years;
m = months;
d = days;
if (nargs < 2)
{
error(sprintf("%s - date and offset values required", __CALLER__));
}
else if (isdate(date))
{
if (nargs == 2)
{
/* Date, {y, m, d} */
if (numcols(years) > 1 && numcols(years) <= 3)
{
try
{
y = col(years, 1);
m = col(years, 2);
d = col(years, 3);
}
catch
{
}
}
else
{
y = years;
}
}
}
else if (isdatetime(date))
{
if (isdatetime(y))
{
(y, m, d) = dt2ymdhms(y);
}
else
{
if (numcols(years) > 1 && numcols(years) >= 3)
{
try
{
y = col(years, 1);
m = col(years, 2);
d = col(years, 3);
}
catch
{
}
}
else
{
y = years;
}
}
date = date[.., 1..2..end];
}
return(date, y, m, d);
}