1827479 Members
2530 Online
109965 Solutions
New Discussion

Continuous day count

 
SOLVED
Go to solution
Niall76
Frequent Advisor

Continuous day count

Hi,

Is there some way in VMS of getting the number of days since a certain date to today? To be precise the number of days since the 10th of April 1988 to today. I currently use a simple excel spreadsheet and enter the value myself, but if VMS can calculate this number for me it would be great.

Kind Regards,

Niall
22 REPLIES 22
Joseph Huber_1
Honored Contributor

Re: Continuous day count


See HELP LEXICAL F$DELTA_TIME.

If You have a system older than VMS 7.3-2 and a fortran compiler, then You may use my version at
http://wwwvms.mpp.mpg.de/~huber/util/main/f$delta_time.HTML

http://www.mpp.mpg.de/~huber
Niall76
Frequent Advisor

Re: Continuous day count

Hi Joseph,

Yes I'm only running version 7.3. I was hoping that this could be done using a Lexical function of some sort. Is this possible?

Regards and Thanks,

Niall
Joseph Huber_1
Honored Contributor

Re: Continuous day count

F$delta_time IS the lexical function You are asking for, but was introduced only with VMS 7.3-2.

So either use my replacement program, or search for some earlier DCL command-files doing the calculation in pure DCL, I think at dcl.openvms.org there was one posted.
http://www.mpp.mpg.de/~huber
Joseph Huber_1
Honored Contributor

Re: Continuous day count

The DCL-only solution was posted by R.Boyd at

http://dcl.openvms.org/stories.php?story=07/01/16/4051929
http://www.mpp.mpg.de/~huber
Niall76
Frequent Advisor

Re: Continuous day count

Thanks Joseph for everything so far, but please can you help me with this Com file. I can't seem to be able to enter in the required paramters correctly. I'm sure I'm making a hash of it.
This is what I enter and get nothing back at all, not even an error:
@time_difference.com; 16-JAN-2008:13:40:00 DELTA_TIME "TIME" 16-JAN-2007:13:40:00

Thanks again,
Niall
Joseph Huber_1
Honored Contributor
Solution

Re: Continuous day count

For me it works:

@time_difference 16-JAN-2008:13:40:00 delta_time "TIME" 16-JAN-2007:13:40:00
sh sym delta_time
DELTA_TIME == "+364-00:00:00.00"

Lost something in downloading from dcl.openvms.org ?
http://www.mpp.mpg.de/~huber
Niall76
Frequent Advisor

Re: Continuous day count

Nope! I just never showed symbol afterwards.

So this works, kind off. for some reason the day i was in 1988 does not, but one year later it does. Any ideas?

Prompt> @time_difference 10-Apr-1989:12:00:00 delta_time "TIME" 8-FEB-2011:00:00:00
Prompt> sh sym DELTA_TIME
DELTA_TIME == "-7974-12:00:00.00"
Prompt> @time_difference 10-Apr-1988:12:00:00 delta_time "TIME" 8-FEB-2011:00:00:00
%DCL-W-IVATIME, invalid absolute time - use DD-MMM-YYYY:HH:MM:SS.CC format
\8-FEB-2011 00:00:00.00-16383-0:0\
%DCL-W-IVATIME, invalid absolute time - use DD-MMM-YYYY:HH:MM:SS.CC format
\8-FEB-2011 00:00:00.00-32767-0:0\

Thanks,
Niall
Hein van den Heuvel
Honored Contributor

Re: Continuous day count

The problem with F$DELTA is that it is limited to 9999 days... roughly 25 years.

So to use it properly you'd have to go through the years in chunks of less than 9999 days.
See example below.

Google finds a good few examples, and the TIME_DIFFERENCE one on OpenVMS.org is fine, but a bit much.
A cure but noisy, general purpose example is:
http://www.convertunits.com/dates/from/Nov+17,+1858/to/Feb+8,+2011

Brute forcing through the years and days instead of a binary search works fine as well, or you can just use math as in other examples.
The example below uses the fact the '29' it odd, thus has the low bit set, and thus is TRUE, whereas 28 is false, to adjust for leap years.

Below two examples to just calculate the days since a reference date (not before 17-NOV-1858).

You can edit in your own reference date to speed it up a little if need be.

Turn into a subroutine as needed to calculate a difference.

Hein

$ type DAY_SINCE_17_NOV_1858.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 = 1858
$ days = 45 - 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 17-NOV-1858 "


For OpenVMS 7.3-2 or better with F$DELTA

$
$ 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
$ days = 0
$ start_date = "17-NOV-"
$ start_year = 1858
$ target_year = 'F$CVT( target,,"YEAR")
$ target_date = target - "''target_year'"
$chunck_loop:
$ IF ( target_year - start_year ) .LE. 25 THEN GOTO last_chunck
$ start_next = start_year + 25
$ days = days + f$elem(0," ",f$delta( start_date + "''start_year'", start_date + "''start_next'" ))
$ start_year = start_next
$ goto chunck_loop
$
$last_chunck:
$ dddd = f$delta( start_date + "''start_year'", target)
$ days = days + f$elem(0," ", f$edit( dddd, "TRIM" ))
$ write sys$output p1, " is ", days, " days since 17-NOV-1858 "







Niall76
Frequent Advisor

Re: Continuous day count

from 10-Apr-1988 to today is less than 9999, it is only 8340 by my calculations so the com file should still have worked, yes?

Just if it is fails with less than 9999, then it will probably fail also with looping it.

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... :)

Thanks,
Niall
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

Hein van den Heuvel
Honored Contributor

Re: Continuous day count

>> I expected 8340 not 8338. Below is me running it:


A little late, but you are correct.
I managed to paste a wrong version of the
code.

The leapyear test should be done before the increment. Sorry.

That makes it 8339.
It becomes 8340 if you want to count inclusive of start and end date for a duration.

The reason why this reply is so late is because I wanted to point out that it was not
my intention to edit the file for a specific start, but to just use an early enough date to handle start and end.

I used 17_NOV_1858 because that's the OpenVMS limit.

Next I tried 1-JAN-1900 because that's the EXCEL base date for use with DATEVALUE.
Handy for testing I thought....
Except that those amateurs at Microsoft got it wrong!
They have year 1900 as a Leap Year! Argh!
So I wasted a good bit of time getting confused by that + my own calculation order problem.

Excel::
text datevalue
1/1/1900 1
2/28/1900 59
3/1/1900 61

2/8/2011 40582
4/10/1988 32243
8339

I guess a handy base date is 1/1/1970.
That's the Unix base date ( UTC )

The code below gives:

$ @DAY_SINCE_1_JAN_1970.COM 11-feb-2011:04:40
11-FEB-2011:04:40 is 15016 days since 1_jan_1970. Unix Epoch Seconds: 1297399200

Confirmed with:

$ perl -e "print time"
1297399257

and also

$ @DAY_SINCE_1_JAN_1970.COM 1-jan-1970
1-JAN-1970 is 0 days since 1_jan_1970. Unix Epoch Seconds: 0

$ @DAY_SINCE_1_JAN_1970.COM 2-jan-1970
2-JAN-1970 is 1 days since 1_jan_1970. Unix Epoch Seconds: 86400

$ type DAY_SINCE_1_JAN_1970.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 = 1969
$ days = -365
$ target_year = 'F$CVT( target,,"YEAR")
$
$year_loop:
$ year = year + 1
$ IF F$CVTIME("1-MAR-''year' -1-",,"DAY") THEN days = days + 1
$ days = days + 365
$ 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:
$ seconds = days*86400 + 3600*F$CVT(p1,,"HOUR") + 60*F$CVT(p1,,"MINUTE") + F$CVT(p1,,"SECOND")
$ write sys$output p1, " is ", days, " days since 1_jan_1970. Unix Epoch Seconds: ", seconds

Cheers,
Hein


btw... the website I referred to reports:

http://www.convertunits.com/dates/from/Apr+10,+1988/to/Feb+8,+2011

"The total number of days between Sunday, April 10th, 1988 and Tuesday, February 8th, 2011 is 8,339 days.

This is equal to exactly 22 years, 9 months, and 29 days.

This does not include the end date, so it's accurate if you're measuring your age in days, or the total days between the start and end date. But if you want the duration of an event that includes both the starting date and the ending date, then it would actually be 8,340 days.

The total time span from 1988-04-10 to 2011-02-08 is 200,136 hours.

This is equivalent to 12,008,160 minutes.

You can also convert 8,339 days to 720,489,600 seconds."

Hein


Niall76
Frequent Advisor

Re: Continuous day count

Thanks guys for all your help. It works perfectly.
Niall
Oswald Knoppers_1
Valued Contributor

Re: Continuous day count

Re. Hein,

"Except that those amateurs at Microsoft got it wrong!"

They claim it was Lotus who got it wrong:

http://support.microsoft.com/kb/214326

:-)

Oswald