04-01-2017, 10:07 AM
The input syntax used for dates in these calendar functions that I have coded, is the same used by the HP Prime built-in functions: YYYY.MMDD.
The valid range of dates is also the range used by the HP Prime built-in functions: from 1582.1015 (Julian day 2299161) to 9999.1231 (Julian day 5373484).
Most functions have a very short coding, because they take avantatge of the HP Prime functions DAYOFWEEK, DDAYS and DATEADD.
Listing [Updated. I corrected a typo found by ggauny@live.fr]
Here are some examples:
Is_Date_Valid(2017.0401) → 1
Is_Date_Valid(2017.0229) → 0
Is_Leap_Year(2017.0401) → 0
Is_Leap_Year(2017) → 0
Is_Leap_Year(2016.0401) → 1
Is_Leap_Year(2016) → 1
Century(2017.0401) → 21
Century(2017) → 21
Year(2017.0401) → 2017
Month(2017.0401) → 4
Day(2017.0401) → 1
Date_to_Julian_Day(2017.0401) → 2457845
Julian_Day_to_Date(2457845) → 2017.0401
Week_Number(2017.0401) → 13
The valid range of dates is also the range used by the HP Prime built-in functions: from 1582.1015 (Julian day 2299161) to 9999.1231 (Julian day 5373484).
Most functions have a very short coding, because they take avantatge of the HP Prime functions DAYOFWEEK, DDAYS and DATEADD.
Listing [Updated. I corrected a typo found by ggauny@live.fr]
PHP Code:
// Calendar functions
// JMB - April 2017
// Valid dates are from 1582.1015 (Julian day 2299161) to 9999.1231 (Julian day 5373484)
#pragma mode( separator(.,;) integer(h32) )
EXPORT Is_Date_Valid(d)
// d:date → 1=valid date, 0=invalid date
BEGIN
IFTE(d<1582.1015 OR d>9999.1231 OR DAYOFWEEK(d)<0, 0, 1);
END;
EXPORT Is_Leap_Year(d)
// d:date or year → 1=leap year, 0=ordinary year
BEGIN
DAYOFWEEK(IP(d)+0.0229) > 0;
END;
EXPORT Century(d)
// d:date or year → century
BEGIN
IP((d-1)/100)+1;
END;
EXPORT Year(d)
// d:date → year
BEGIN
IP(d);
END;
EXPORT Month(d)
// d:date → month
BEGIN
IP(FP(d)*100);
END;
EXPORT Day(d)
// d:date → day
BEGIN
FP(FP(d)*100)*100;
END;
EXPORT Date_to_Julian_Day(d)
// d:date → Julian day
BEGIN
2299161+DDAYS(1582.1015,d);
END;
EXPORT Julian_Day_to_Date(jd)
// jd:Julian day → date
BEGIN
DATEADD(1582.1015,jd-2299161);
END;
EXPORT Week_Number(d)
// d:date → week number (ISO 8601)
BEGIN
LOCAL yr:=Year(d), mn:=Month(d), dy:=Day(d);
LOCAL DoW_0101:=IFTE(yr==1582,1,DAYOFWEEK(yr+0.0101));
LOCAL DoW_Yp1_0101:=IFTE(yr==9999,6,DAYOFWEEK(yr+1.0101));
LOCAL wn:=IP((IFTE(yr==1582,Date_to_Julian_Day(d)-2298884,DDAYS(yr+0.0101,d))+DoW_0101-1)/7);
IF mn==12 AND DoW_Yp1_0101≤4 AND (32-dy)<DoW_Yp1_0101 THEN
RETURN 1;
ELSE
IF DoW_0101≤4 THEN
RETURN wn+1;
ELSE
IF mn==1 AND (9-dy)>DoW_0101 THEN
RETURN Week_Number(yr-1+0.1231);
ELSE
RETURN wn;
END;
END;
END;
END;
Here are some examples:
Is_Date_Valid(2017.0401) → 1
Is_Date_Valid(2017.0229) → 0
Is_Leap_Year(2017.0401) → 0
Is_Leap_Year(2017) → 0
Is_Leap_Year(2016.0401) → 1
Is_Leap_Year(2016) → 1
Century(2017.0401) → 21
Century(2017) → 21
Year(2017.0401) → 2017
Month(2017.0401) → 4
Day(2017.0401) → 1
Date_to_Julian_Day(2017.0401) → 2457845
Julian_Day_to_Date(2457845) → 2017.0401
Week_Number(2017.0401) → 13