home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
fdater.zip
/
FDATER.REX
< prev
next >
Wrap
OS/2 REXX Batch file
|
1995-04-29
|
12KB
|
334 lines
/* to make Fdater an internal routine, uncomment the following line. */
/* FDATER: procedure */
signal on novalue
function = translate(arg(1)) /* put arg(1) in upper case */
invalue = arg(2)
/*===============================================================
FDATER: A REXX implementation of the Truedate date arithmetic routine
Version 4.0 1995 April 29
======================================================================
AUTHOR: Stephen Ferg
608 N. Harrison Street
Arlington, VA 22203-1416
USA
telephone (voice, not FAX): (703) 525-2241
CompuServe ID : 73377,1157
Internet : 73377.1157@compuserve.com
REVISION HISTORY
--------------------------
4.0 (1995 April 29) Stephen Ferg
Added code to translate to and from TrueDate AbsDate to REXX BaseDate
Renamed routines to reflect usage of REXX base dates
================================================================*/
MinAbsDate = 1 /* JANUARY 1, 0001 */
DaysInOrdinaryYr = 365
DaysIn004YrGroup = 1461 /*(DaysInOrdinaryYr * 4) + 1*/
DaysIn100YrGroup = 36524 /*(DaysIn004YrGroup * 25) - 1*/
DaysIn400YrGroup = 146097 /*(DaysIn100YrGroup * 4) + 1*/
MaxAbsDate = 3652059 /* DECEMBER 31, 9999 */
JANdays = 31
FEBshort = 28
MARdays = 31
APRdays = 30
MAYdays = 31
JUNdays = 30
JULdays = 31
AUGdays = 31
SEPdays = 30
OCTdays = 31
NOVdays = 30
DECdays = 31
constants = "MinAbsDate MaxAbsDate DaysInOrdinaryYr",
"DaysIn004YrGroup DaysIn100YrGroup DaysIn400YrGroup",
"JANdays FEBshort MARdays APRdays MAYdays JUNdays",
"JULdays AUGdays SEPdays OCTdays NOVdays DECdays "
select
when function= "BASE2CAL" then RETURN BaseDate_To_CalDate(invalue)
when function= "CAL2BASE" then RETURN CalDate_To_BaseDate(invalue)
when function= "MONTHNAME" then RETURN MonthName(invalue)
when function= "DOWNAME" then RETURN DowName(invalue)
when function= "DOWNUM" then RETURN DowNum(invalue)
when function= "ISLEAPYEAR" then RETURN IsLeapYear(invalue)
otherwise
RETURN "ERROR: Invalid function name" function
end
/*--------------[ end FDATER main routine ]----------------*/
/**/
/*==============================================================*/
IsLeapYear : procedure expose (constants)
/*==============================================================*/
arg CalYear
if \Datatype(CalYear,"W") then
RETURN "ERROR: Year parm is not a whole number."
if CalYear < 1 | CalYear > 9999 then
RETURN "ERROR: Year parm is not in range 1 - 9999."
Mod400 = CalYear // 400
if Mod400 = 0 then RETURN 1
Mod100 = Mod400 // 100
if Mod100 = 0 then RETURN 0
Mod004 = Mod100 // 4
if Mod004 = 0 then RETURN 1
RETURN 0
/*===============================================================*/
DoWnum : procedure
/*Calculate the day of the week from the absolute date*/
/*===============================================================*/
BaseDate = arg(1)
AbsDate = BaseDate + 1 /* REXX BaseDate ==> TrueDate AbsDate */
if \Datatype(AbsDate,"W") then
RETURN "ERROR: parameter is not a whole number."
/*add 1, so that DoWnum is in range 1..7 rather than 0..6*/
/*DoWnum 1 is Sunday, DoWnum 2 is Monday ... DoWnum 7 is Saturday*/
RETURN ( AbsDate // 7) + 1
/*===============================================================*/
BumpMonth: /* note: CalMonth and CalDay are exposed */
/*===============================================================*/
CalMonth = CalMonth + 1
CalDay = CalDay - arg(1) /* arg(1) = Monthdays */
RETURN
/**/
/*==============================================================*/
MonthName: procedure
/* Calculate English-language name of the month */
/*===============================================================*/
arg CalMonth
if CalMonth = 1 then RETURN 'January'
if CalMonth = 2 then RETURN 'February'
if CalMonth = 3 then RETURN 'March'
if CalMonth = 4 then RETURN 'April'
if CalMonth = 5 then RETURN 'May'
if CalMonth = 6 then RETURN 'June'
if CalMonth = 7 then RETURN 'July'
if CalMonth = 8 then RETURN 'August'
if CalMonth = 9 then RETURN 'September'
if CalMonth = 10 then RETURN 'October'
if CalMonth = 11 then RETURN 'November'
if CalMonth = 12 then RETURN 'December'
RETURN 'ERROR: INVALID MONTH NUMBER'
/*===============================================================*/
DOWNAME : procedure
/* Calculate English-language name of the day of the week */
/*===============================================================*/
arg DayOfWeekNum
if DayOfWeekNum = 1 then RETURN 'Sunday'
if DayOfWeekNum = 2 then RETURN 'Monday'
if DayOfWeekNum = 3 then RETURN 'Tuesday'
if DayOfWeekNum = 4 then RETURN 'Wednesday'
if DayOfWeekNum = 5 then RETURN 'Thursday'
if DayOfWeekNum = 6 then RETURN 'Friday'
if DayOfWeekNum = 7 then RETURN 'Saturday'
RETURN 'ERROR: INVALID DAY OF WEEK NUMBER'
/**/
/*==============================================================*/
BaseDate_To_CalDate: procedure expose (constants)
/* Convert an absolute date into a calendar date */
/*===============================================================*/
BaseDate = arg(1)
AbsDate = BaseDate + 1 /* REXX BaseDate ==> TrueDate AbsDate */
if \Datatype(AbsDate,"W") then
RETURN "ERROR: parameter is not a whole number."
Num400YrGroups = AbsDate % DaysIn400YrGroup
Num400YrModYrs = AbsDate // DaysIn400YrGroup
if Num400YrModYrs = 0 then
do /*absolute date fits exactly into a 400-year group*/
JulianDate = 366
CalYear = (400 * Num400YrGroups)
end
else
do
Num100YrGroups = Num400YrModYrs % DaysIn100YrGroup
Num100YrModYrs = Num400YrModYrs // DaysIn100YrGroup
if Num100YrModYrs = 0 then
do /*absolute date fits exactly into a 100-year group*/
JulianDate = 365
CalYear = (400 * Num400YrGroups) ,
+ (100 * Num100YrGroups) ;
end
else
do
Num004YrGroups = Num100YrModYrs % DaysIn004YrGroup
Num004YrModYrs = Num100YrModYrs // DaysIn004YrGroup
if Num004YrModYrs = 0 then
do
/*absolute date fits exactly into a 4-year group*/
JulianDate = 366
CalYear = (400 * Num400YrGroups) ,
+ (100 * Num100YrGroups) ,
+ ( 4 * Num004YrGroups) ;
end
else
do
Num001YrGroups = Num004YrModYrs % DaysInOrdinaryYr
Num001YrModYrs = Num004YrModYrs // DaysInOrdinaryYr
if Num001YrModYrs = 0 then
do
/*absolute date fits exactly into a 1-year group*/
JulianDate= 365
CalYear = (400 * Num400YrGroups) ,
+ (100 * Num100YrGroups) ,
+ ( 4 * Num004YrGroups) ,
+ ( 1 * Num001YrGroups) ;
end
else
do
/*absolute date doesn't fit exactly into any group*/
JulianDate= Num001YrModYrs
/*Add 1 to convert a year count into an ordinal year*/
/*E.g. Absolute day 5 is Jan. 5 of year 1, not year 0*/
CalYear = (400 * Num400YrGroups) ,
+ (100 * Num100YrGroups) ,
+ ( 4 * Num004YrGroups) ,
+ ( 1 * Num001YrGroups) ,
+ 1 ;
end
end
end
end
/**/
/*determine number of days in February in this year*/
LeapYearFlag = IsLeapYear(CalYear)
FEBdays = FEBshort + LeapYearFlag
/*Initialize month number to month #1 */
CalMonth = 1
/*Initialize day-of-month to Julian date*/
CalDay = JulianDate
/*Subtract days of elapsed months from day-of-month to get final
day-of-month.
At the same time, increment month-number for each elapsed month.*/
if CalDay > JANdays then do
call BumpMonth JANdays
if CalDay > FEBdays then do
call BumpMonth FEBdays
if CalDay > MARdays then do
call BumpMonth MARdays
if CalDay > APRdays then do
call BumpMonth APRdays
if CalDay > MAYdays then do
call BumpMonth MAYdays
if CalDay > JUNdays then do
call BumpMonth JUNdays
if CalDay > JULdays then do
call BumpMonth JULdays
if CalDay > AUGdays then do
call BumpMonth AUGdays
if CalDay > SEPdays then do
call BumpMonth SEPdays
if CalDay > OCTdays then do
call BumpMonth OCTdays
if CalDay > NOVdays then do
call BumpMonth NOVdays
end
end
end
end
end
end
end
end
end
end
end
RETURN CalYear CalMonth CalDay
/**/
/*==============================================================*/
CalDate_To_BaseDate: procedure expose (constants)
/* Convert a calendar date into an absolute date */
/*===============================================================*/
arg CalYear CalMonth CalDay .
if \Datatype(CalDay ,"W") then
RETURN "ERROR: CalDay (word 3) is not a whole number."
if \Datatype(CalMonth ,"W") then
RETURN "ERROR: CalMonth (word 2) is not a whole number."
if \Datatype(CalYear ,"W") then
RETURN "ERROR: CalYear (word 1) is not a whole number."
/* ===============================================================
Subtract 1 to convert an ordinal year number into a count of years
elapsed since "the start of time". Examples:
During year ONE, ZERO years have actually elapsed from day one.
During year TWO, ONE year has actually elapsed from day one.
=============================================================== */
Num400YrGroups = (CalYear - 1) % 400
Num400YrModYrs = (CalYear - 1) // 400
Num100YrGroups = Num400YrModYrs % 100
Num100YrModYrs = Num400YrModYrs // 100
Num004YrGroups = Num100YrModYrs % 4
Num004YrModYrs = Num100YrModYrs // 4
Num001YrGroups = Num004YrModYrs % 1
/*Initialize absolute date to number of days elapsed in previous years*/
AbsDate = ( Num400YrGroups * DaysIn400YrGroup ) ,
+ ( Num100YrGroups * DaysIn100YrGroup ) ,
+ ( Num004YrGroups * DaysIn004YrGroup ) ,
+ ( Num001YrGroups * DaysInOrdinaryYr )
/*determine number of days in February in this year*/
LeapYearFlag = IsLeapYear(CalYear)
FEBdays = FEBshort + LeapYearFlag
/*Initialize Julian date to days elapsed in this month*/
JulianDate = CalDay
/*add days of previous months in this year to get final Julian date*/
if CalMonth > 1 then JulianDate = JulianDate + JANdays
if CalMonth > 2 then JulianDate = JulianDate + FEBdays
if CalMonth > 3 then JulianDate = JulianDate + MARdays
if CalMonth > 4 then JulianDate = JulianDate + APRdays
if CalMonth > 5 then JulianDate = JulianDate + MAYdays
if CalMonth > 6 then JulianDate = JulianDate + JUNdays
if CalMonth > 7 then JulianDate = JulianDate + JULdays
if CalMonth > 8 then JulianDate = JulianDate + AUGdays
if CalMonth > 9 then JulianDate = JulianDate + SEPdays
if CalMonth > 10 then JulianDate = JulianDate + OCTdays
if CalMonth > 11 then JulianDate = JulianDate + NOVdays
/*add Julian date to days of previous years to get final absolute date*/
AbsDate = AbsDate + JulianDate
BaseDate = AbsDate - 1 /* TrueDate AbsDate ==> REXX BaseDate */
RETURN BaseDate