Operating System - OpenVMS
1752790 Members
6441 Online
108789 Solutions
New Discussion юеВ

Re: Continuous day count

 
SOLVED
Go to solution
Hein van den Heuvel
Honored Contributor

Re: Continuous day count

>> Maybe it possible to add a value to the returned DELTA_TIME. Say the number of days from 10-APR-1988 to 31-Jan-1999 and then add this number of days to the returned DELTA_TIME and use the start date to be 01-Jan-2000. How do i do that then... :)


That's exactly what my second example does in a very generic format, using 25 year chunks since the beginning of (OpenVMS) time.

You could easily simplify picking a different reference date for which you know you will need only one more F$DELTA and stay in that range for the supported future or the script.

Your example...

$ write sys$output F$DELTA ( "10-APR-1988", "01-Jan-2000")
4283 00:00:00.00
$ write sys$output F$DELTA ( "01-Jan-2000", "08-Feb-2011")
4056 00:00:00.00
$ write sys$output F$DELTA ( "10-APR-1988", "08-Feb-2011")
8339 00:00:00.00
$ write sys$output 4283 + 4056
8339

Hein

Joseph Huber_1
Honored Contributor

Re: Continuous day count

Well, define debug$dcl 1, then You will see

$ new_time = f$cvtime(f$fao(bformat,delta_value),,component)
%DCL-W-IVATIME, invalid absolute time - use DD-MMM-YYYY:HH:MM:SS.CC format
\8-FEB-2011 13:40:00.00-16383-0:0\

Seems the author is doubling the delta-time testing iteratively. And since the difference is >8192 , next is 163nn, giving an illegal combined time for DCL.
So this time_difference.com in fact is not working up to 9999 days, but only for something like 8192.

Or use my above mentioned program, it works definetly up to 9999 days:

f$delta_time/log temp 10-Apr-1988:13:40:00 8-FEB-2011:13:40:00
8339 00:00:00.00

BTW, if You are interested in just counting days, then there is another possibility:
use a "Julian Day number" routine like LIB$DAY for the two dates, and take the difference of the two resulting numbers: this works for dates back to the modified Julian Date day 0 of 17-NOV-1859.
Or even a general julian date program jd* like I have on
http://wwwvms.mpp.mpg.de/~huber/util/


http://www.mpp.mpg.de/~huber
Joseph Huber_1
Honored Contributor

Re: Continuous day count

Using
http://wwwvms.mpp.mpg.de/~huber/util/main/mjdv.for

it is as short as:

MPIW10_HUB>@day_diff 1-jan-1982 today
44970
55600
TDIFF = 10630 Hex = 00002986 Octal = 00000024606

$!day_diff.com:
$ mjdv 'p1'
$ d1=f$integer(mjdn)
$ mjdv 'p2'
$ d2=f$integer(mjdn)
$ tdiff=d2-d1
$ show symbol tdiff
http://www.mpp.mpg.de/~huber
Niall76
Frequent Advisor

Re: Continuous day count

omg! My head is getting sore now :)

I can't make head nor tail from that last link you posted, can you paste the text in here.

I looked at your julian day counter, but it appears to be two days wrong or I miss counted somewhere. I expected 8340 not 8338. Below is me running it:

Prompt> @DAY_SINCE_10_APR_1988 8-FEB-2011:13:40:00
$ TYP DAY_SINCE_10_APR_1988.COM;
$ target = 123 ! This integer will become a string if Convert time works
$ target = F$CVT(P1,"ABSOLUTE","DATE")
$ IF F$TYPE(target) .NES. "STRING" THEN EXIT 16
$ year = 1988
$ days = 265 - 365
$ target_year = 'F$CVT( target,,"YEAR")
$
$year_loop:
$ year = year + 1
$ days = days + 365
$ IF F$CVTIME("1-MAR-''year' -1-",,"DAY") THEN days = days + 1 ! 28=false, 29=true
$ IF year.LT.target_year THEN GOTO year_loop
$
$ date = "1-JAN-''year'"
$day_loop:
$ IF date .EQS.target THEN GOTO done
$ date = F$CVT("''date' +1-","ABSOLUTE","DATE")
$ days = days + 1
$ goto day_loop
$
$ done:
$ write sys$output p1, " is ", days, " days since 10-Apr-1988 "
8-FEB-2011:13:40:00 is 8338 days since 10-Apr-1988

Thanks,
Niall

Joseph Huber_1
Honored Contributor

Re: Continuous day count

Niall, are You referring to
http://wwwvms.mpp.mpg.de/~huber/util/main/mjdv.for ?
If You are using MS internet explorer, then yes, it does not deal right with .FOR files :-)
I attach it .
My run looks like
day_diff 10-APR-1988 today
8339

So it is correctly calculating days between dates, just add 1 in the day_diff.com above tdiff=d2-d1+1

http://www.mpp.mpg.de/~huber
John Gillings
Honored Contributor

Re: Continuous day count

Niall,

This procedure will work on V7.2. I believe it's the fastest possible implementation (left as an exercise to figure out how it works ;-)

I did have a version that worked for ranges greater than 10000 days, but I can't find it at the moment.

@SUBTIMES "10-APR-1988" "TODAY"
DELTA == "8340 00:00:00.00"


SUBTIMES.COM
$ ON WARNING THEN EXIT
$ tt=F$CVTIME(p1)
$ GOSUB x
$ b0=d
$ tt=F$CVTIME(p2)
$ GOSUB x
$ b1=d
$ d[32,32]=%XF0000000
$ d[0,32]=0
$ l0=F$CVUI(0,30,b0)
$ l1=F$CVUI(0,30,b1)
$ IF l0.LT.l1
$ THEN
$ d[0,30]=.NOT.((l1-l0).AND.%X3FFFFFFF)
$ d[30,30]=.NOT.(F$CVUI(30,30,b1)-F$CVUI(30,30,b0))
$ ELSE
$ d[0,30]=.NOT.((%X40000000+l1-l0).AND.%X3FFFFFFF)
$ d[30,30]=.NOT.(F$CVUI(30,30,b1)-F$CVUI(30,30,b0)-1)
$ ENDIF
$ delta==F$FAO("!%D",F$CVUI(32,32,F$FAO("!AD",8,d)))
$ SHOW SYM delta
$ EXIT
$ x:
$ d[32,32]=0
$ d[0,32]=0
$ b=60
$ Loop: d[b,1]=1
$ IF F$CVTIME(F$FAO("!%D",F$CVUI(32,32,F$FAO("!AD",8,d)))).GTS.tt THEN d[b,1]=0
$ b=b-1
$ IF b.GT.0 THEN GOTO loop
$ RETURN
A crucible of informative mistakes
John Gillings
Honored Contributor

Re: Continuous day count

Niall,

Actually, since you only want DAYS between dates (as opposed to a delta time between two absolute datetimes), it's much easier.

This procedure will calculate the number of days between any two dates from 17-NOV-1858 through to 18-JUN-9990. First parameter is the start date, second is end date (defaults to TODAY)

$ @dayssince 10-apr-1988
DAYS = 8340 Hex = 00002094 Octal = 00000020224
$ @dayssince 10-apr-1888
DAYS = 44864 Hex = 0000AF40 Octal = 00000127500
$ @dayssince 17-nov-1858 18-jun-9990
DAYS = 2970000 Hex = 002D5190 Octal = 00013250620

DAYSSINCE.COM
$ ON WARNING THEN EXIT
$ s=F$CVTIME(p1,"ABSOLUTE","DATE")
$ e=F$CVTIME(p2,,"DATE")
$ c=0
$ d=5000
$ G: IF F$CVTIME("''s'+''d'-0",,"DATE").LTS.e
$ THEN
$ c=c+d
$ s=F$CVTIME("''s'+''d'-0","ABSOLUTE")
$ GOTO G
$ ENDIF
$ x=d
$ F: t=F$CVTIME("''s'+''x'-0",,"DATE")
$ IF t.NES.e
$ THEN
$ d=(d+1)/2
$ IF t.LTS.e
$ THEN
$ x=x+d
$ ELSE
$ x=x-d
$ ENDIF
$ GOTO F
$ ENDIF
$ days=c+x
$ SHOW SYM days
A crucible of informative mistakes
WW304289
Frequent Advisor

Re: Continuous day count

And here's the C version (could not resist :-)

$ pipe cc days ; link days ; run days
8340 days
$

days.c
------
#include
#include

int main() {
static struct tm tm_beg;
int days;

tm_beg.tm_mday = 10; /* 10th */
tm_beg.tm_mon = 3; /* April */
tm_beg.tm_year = 88; /* 1988 */
tm_beg.tm_isdst = -1; /* don't know if this is STD or DST in your timezone */

days = (time(0) - mktime(&tm_beg)) / (24*3600) + 1;
printf("%d days\n", days);
}
Joseph Huber_1
Honored Contributor

Re: Continuous day count

WW304289, that's the most clever !

Just a question about the "+1" :
would one like the number of days between yesterday and today to be 2 ?
I prefer to leave off "+1".
http://www.mpp.mpg.de/~huber
WW304289
Frequent Advisor

Re: Continuous day count

Joseph,

"
Just a question about the "+1" :
would one like the number of days between yesterday and today to be 2 ?
I prefer to leave off "+1".
"

It depends on whether you want to count current (partial) day as a day. If you don't, leave "+1" off. Probably, NOT counting partial day is more intuitive than counting it.

Thanks,
-Boris