View Raw SPL
/*****************************************************************************
* *
* JULYMD.SPL Copyright (C) 1998-2024 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Converts a series to Julian dates *
* *
* Revisions: 9 Jul 1998 RRR Creation *
* 17 Mar 2005 RRR julvec iyyy assignment fix *
* 14 Nov 2024 RRR option for separate Y, M, D input *
* *
*****************************************************************************/
#define IGREG (15+31*(10+12*1582))
#define JGREG 2299161
#if @HELP_JULYMD
JULYMD
Purpose: Converts a series of yymmdd values to Julian dates
Syntax: Julymd(y, m, d)
y - A scalar or series, the year values.
m - A scalar or series, the month values.
d - A scalar or series, the day values.
Alternate Syntax: Julymd(dtser, format)
dtser - a series containing date/time values
format - an optional integer, the value format.
0:yymmdd (default)
1:yyyymmdd
Returns: A series or array of Julian integers
Example:
W1: {1998, 1999, 2000}
W2: {1, 1, 1}
W3: {10, 11, 15}
W4: julymd(w1, w2, w3)
W1 contains the year values.
W2 contains the month values.
W3 contains the day values.
W4 contains the date series:
1-10-1998
1-11-1999
1-15-2000
Example:
W1: julymd(1998..2000, 1, {10, 11, 15})
Same as above except the year, month and day values are entered
directly as series.
W1 contains the date series:
1-10-1998
1-11-1999
1-15-2000
Example:
W1: julymd(1998..2000, 1, {10, 11, 45})
Same as above except the the last day value of 45 causes the
resulting month to rollover.
W1 contains the date series:
1-10-1998
1-11-1999
2-14-2000
Example:
W1: {980101, 980102, 980103, 980112}
W2: julymd(w1);
W3: xy(w2, {1, 2, 3, 4})
W2 contains the series {2450815, 2450816, 2450817, 2450826}
Each value is the Julian representation of the original
date/time values of W1. In this case, W1 is specified in
composite YYMMDD format.
Example:
W1: {19980101, 19980102, 19980103, 19980112}
W2: julymd(w1, 1);
W3: xy(w2, {1, 2, 3, 4})
Same as the first example, but the date/time format is
composite YYYYMMDD.
Example:
W1: julymd(1998, 1, {1..3, 12})
W2: xy(w1, {1, 2, 3, 4})
Same as above except the year, month and day inputs are
entered as separate values.
Remarks:
JULYMD creates a date series by combining individual year,
month and day values or by extracting year, month and day
values from composite YYYYMMDD integers.
JULYMD attempts to recognizes the YYYYMMDD and YYMMDD
date/time formats for composite inputs.
For separate Y, M, D inputs, out of range month and day values
are rolled over.
For composite YYYYMMDD inputs, 0 is returned for date/time values
that cannot be converted.
See Also:
Julstr
#endif
/* convert year, month, day to Julian */
julymd(y, m, d)
{
local val, str, format, len;
if (not(argc == 3))
{
if (isstring(y))
{
return(julstr(y));
}
else if (not(isarray(y)))
{
error(sprintf("%s - series required", __FUNC__));
}
/* figure out format */
if (argc < 2)
{
val = castint(y[1]);
str = sprintf("%ld", castint(y[1]));
if (strlen(str) == 8)
{
format = 1;
}
else
{
format = 0;
}
}
else
{
format = m;
}
/* get individual yy mm dd series */
if (format == 0)
{
/* yymmdd */
m = int(y / 100) % 100;
d = int(y % 100);
/* convert 2 digit year to 4 digit */
y = int(y / 10000);
y = yytoyyyy(y);
}
else if (format == 1)
{
/* yyyymmdd */
m = int(y / 100) % 100;
d = int(y % 100);
y = int(y / 10000);
}
else
{
error(sprintf("julymd - invalid format %d", format));
}
}
else
{
if (isarray(y) || isarray(m) || isarray(d))
{
len = vmax(length(y), length(m), length(d));
if (isscalar(y))
{
y = rep({y}, len);
}
if (isscalar(m))
{
m = rep({m}, len);
}
if (isscalar(d))
{
d = rep({d}, len);
}
}
}
/* internal conversion */
jmd = julfromymd(y, m, d);
return(jmd);
}
/* vectorized Julian conversion */
julvec(mm, id, iyyy)
{
local jul;
local ja, jy, jm;
local t;
if (not(all(mm) && all(id) && all(iyyy)))
{
return(zeros(length(mm), 1));
}
t = iyyy == 0;
// no Julian year 0
iyyy = iyyy * not(t) + t;
t = iyyy < 0;
iyyy = iyyy * not(t) + (iyyy + 1) * t;
t = mm > 2;
jy = t * iyyy + (iyyy - 1) * not(t);
jm = t * (mm + 1) + not(t) * (mm + 13);
jul = int((floor(365.25 * jy) + floor(30.6001 * jm) + id + 1720995));
t = (id + 31 * (mm + 12 * iyyy)) >= IGREG;
ja = int(0.01 * jy);
inc = 2 - ja + int(0.25 * ja);
jul = int(t * (jul + inc) + not(t) * jul);
if (isarray(jul))
{
setvunits(jul, "Daily", -1);
}
return(jul);
}
/* convert two digit year to four digit year */
yytoyyyy(yy)
{
local y2kmode, locale, y2kmode, dt_y2k_offset;
local current_century, base_century, year;
y2kmode = getconf("dt_y2k_format") == "1";
dt_y2k_offset = numstr(getconf("dt_y2k_offset"));
locale = getconf("locale_idate");
/* use yyyy-mm-dd to get current year */
setconf("locale_idate", "2");
year = numstr(getdate());
setconf("locale_idate", locale);
if (y2kmode)
{
/* use 50 year window */
locale = getconf("locale_idate");
base_century = int(100 * int((year + dt_y2k_offset) / 100));
if (yy <= dt_y2k_offset)
{
yy += base_century;
}
else
{
yy += base_century - 100;
}
}
else
{
/* just use current century */
current_century = int(100 * int(year / 100));
yy += current_century;
}
return(yy);
}