
A bit of fun....
Started by Glenn Meyers, Dec 19 2002 07:27 PM
14 replies to this topic
#1
Posted 19 December 2002 - 07:27 PM
Suppose we have a bit of fun.
What is the fastest logic for calculating the number of days in that month for any given date that the logic is executed?
For example...the logic would return 28 if the routine was run any day in February. 30 for September. Etc.
Oh, and Merry Christmas you lot!
Glenn
What is the fastest logic for calculating the number of days in that month for any given date that the logic is executed?
For example...the logic would return 28 if the routine was run any day in February. 30 for September. Etc.
Oh, and Merry Christmas you lot!
Glenn
#3
Posted 20 December 2002 - 02:43 AM
Assumptions:
1) Using standard PRO-IV logic commands CDATE, PIC and CONV
2) Checking only within valid dates covered with CDATE
3) Date is entered into variable #D, stored in PRO-IV internal date format
4) Output is number of days, stored in string variable $DAYS
5) Looking for fewest logic statements
Logic:
$D = CDATE(#D,'YYYYMM')
IF $D(5,6) = '12' THEN $D = '31' EXIT;
#N = CDATE($D(1,4) + PIC(CONV($D(5,6)) + 1,'99') + '01','YYYYMMD
$DAYS = CDATE(#N - 1,'DD')
1) Using standard PRO-IV logic commands CDATE, PIC and CONV
2) Checking only within valid dates covered with CDATE
3) Date is entered into variable #D, stored in PRO-IV internal date format
4) Output is number of days, stored in string variable $DAYS
5) Looking for fewest logic statements
Logic:
$D = CDATE(#D,'YYYYMM')
IF $D(5,6) = '12' THEN $D = '31' EXIT;
#N = CDATE($D(1,4) + PIC(CONV($D(5,6)) + 1,'99') + '01','YYYYMMD
$DAYS = CDATE(#N - 1,'DD')
#5
Posted 20 December 2002 - 02:50 AM
Rick,
It could be a problem with the forum not liking all those quotes and brackets. You could try with double quotes instead.. I'll take a look at it later.
Rob D.
It could be a problem with the forum not liking all those quotes and brackets. You could try with double quotes instead.. I'll take a look at it later.
Rob D.
#6
Posted 20 December 2002 - 09:11 AM
How about this global logic:
N PARMS(#D)
$M = CDATE(#D, 'MM')
WHILE CDATE(#D, 'MM') = $M
#D += 1
ENDWHILE
RETURN(CONV(CDATE(#D - 1, 'DD')))
N PARMS(#D)
$M = CDATE(#D, 'MM')
WHILE CDATE(#D, 'MM') = $M
#D += 1
ENDWHILE
RETURN(CONV(CDATE(#D - 1, 'DD')))
#9
Posted 21 December 2002 - 12:20 PM
If the operation is going to be done several times in a function, the fastest way is very probably the not-much-fun way eg:
Initialize an array with the number of days in each month..
(I know, I know, leap centuries..
but there aren't any more within the range of ProIV)
and Happy Holidays to those who don't
Initialize an array with the number of days in each month..
DEFINE #MonthLength(12, 2.0)Then when you need a day count use something classical like..
#MonthLength(1) = 31
#MonthLength(2) = -99 [won't be using this one]
#MonthLength(3) = 31
etc..
(I know, I know, leap centuries..
but there aren't any more within the range of ProIV)
$month = CDATE(#theDate, 'MM')Or (under the influence of Jonathan) something like..
IF $month <> '02' THEN
#dayCount = #MonthLength(CONV($month))
ELSE
IF REM(CONV(CDATE(#theDate,'YYYY')), 4) = 0 THEN
#dayCount = 29
ELSE
#dayCount = 28
ENDIF
ENDIF
$date = CDATE(#theDate, 'YYYYMMDD')A Merry Christmas to those who celebrate it
IF $date(5,6) <> '02'
#dayCount = #MonthLength(CONV($date(5,6)))
ELSE
#dayCount = CONV( CDATE( CDATE($date(1,4) + '0301', 'YYYYMMDD') - 1, 'DD') )
ENDIF
and Happy Holidays to those who don't
Nothing's as simple as you think
#12
Posted 23 December 2002 - 04:24 PM
Funny.
That's what my girlfriend said.
Is this better?
That's what my girlfriend said.
Is this better?
STEP CONV(CDATE(@DATE, 'MM'))
1 #days = 31
2 #days = CDATE(CDATE(@DATE,'YYYY') + '03' + CDATE(@DATE, 'DD'), 'YYYYMMDD) - @DATE
3 #days = 31
4 #days = 30
5 #days = 31
6 #days = 30
7 #days = 31
8 #days = 31
9 #days = 30
10 #days = 31
11 #days = 30
12 #days = 31
Nothing's as simple as you think
#13
Posted 23 December 2002 - 05:33 PM
Mike Schoen was pipped at the post by Richard Bassett's last entry (which I modified to use CALL instead of STEP, to make the code reuseable in a loop).
The wooden spoon goes to Cleve Haynes, whose routine took almost 20 times as long as the winning entry and had to be changed to make it safe (call by reference).
Full results (in seconds) for 222308 iterations using a range of dates between 1/1/1800 and the current date are as follows:
R Bassett 2
M Schoen 4
R Bassett 6
R San Soucie 7
J Weeks 12
C Haynes 37
Ralph
The wooden spoon goes to Cleve Haynes, whose routine took almost 20 times as long as the winning entry and had to be changed to make it safe (call by reference).
Full results (in seconds) for 222308 iterations using a range of dates between 1/1/1800 and the current date are as follows:
R Bassett 2
M Schoen 4
R Bassett 6
R San Soucie 7
J Weeks 12
C Haynes 37
Ralph
#14
Posted 31 December 2002 - 04:23 PM
String CASEs are faster than numerics:
CASE CDATE(#D,'MM')
WHEN '02':
#E = 28
#Y = CONV(CDATE(#D,'YYYY'))
IF REM(#Y,4) ELSE
#E += 1
IF REM(#Y,100) ELSE
#E -= 1
IF REM(#Y,400) ELSE #E += 1;
ENDIF
ENDIF
WHEN '04','06','09','11': #E = 30
OTHERWISE: #E = 31
ENDCASE
#15
Posted 31 December 2002 - 06:50 PM
This is almost the solution I used.
I did the month conversion to a number for a bit faster comparisions:
#M = CONV(CDATE (#D,'MM'))
CASE #M .....etc.
I also inverted the order of case checking to check for the most likely scenario (months with 31 days) first.
I did the month conversion to a number for a bit faster comparisions:
#M = CONV(CDATE (#D,'MM'))
CASE #M .....etc.
I also inverted the order of case checking to check for the most likely scenario (months with 31 days) first.
Reply to this topic

0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users