Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

check date against an given age

7 views
Skip to first unread message

DTL

unread,
Nov 11, 2009, 11:37:18 AM11/11/09
to
Hi Folks,

I'm needing some help to write the following in DCL:

if person's age >= 60 years old then...

knowning that birth date in file has format JJ/MM/AA

Thanks for your help.

Didier

Jan-Erik Söderholm

unread,
Nov 11, 2009, 11:44:46 AM11/11/09
to

Is that Jour/Mois/Ann�e (Day/Month/Year) ?

Mike Rechtman

unread,
Nov 11, 2009, 12:38:07 PM11/11/09
to
What version of VMS?
IIRC there was an addition to DCL lexicals in V8.? to do date subtraction.

--
Mike R.
Home: http://alpha.mike-r.com/
QOTD: http://alpha.mike-r.com/php/qotd.php
No Micro$oft products were used in the URLs above, or in preparing this message.
Recommended reading: http://www.catb.org/~esr/faqs/smart-questions.html#before

Ken Fairfield

unread,
Nov 11, 2009, 12:50:32 PM11/11/09
to
On Nov 11, 8:37 am, DTL <didier.mora...@gmail.com> wrote:
> Hi Folks,
>
> I'm needing some help to write the following in DCL:
>
> if person's age >= 60 years old then...
>
> knowning that birth date in file has format JJ/MM/AA

Assuming, as Jan-Erik asked, that JJ/MM/AA is day-month-year
(in english), a little use of F$CvTime and F$Element will do the
trick. :-)

I am making one assumption, possibly not justified, that
the output of F$CvTime("TODAY",,"DATE"), for example,
is in yyyy-mm-dd format. It may be that this format
is, or can be, overridden by the system manager...I was
looking at LIB$DT_STARTUP.COM and the
LIB$DATE_FORMAT_xx logical names, but I've forgotten
how and when one works these into DCL...

In any case, the first step is to form the comparison
date the represents 60 years before today. That's
pretty easy:

$ now = F$CvTime("TODAY",,"DATE")
$ y60 = F$Integer(F$Element(0, "-", now)) - 60
$ d60 = "''y60'-''F$Element(1,"-",now)'-''F$Element(2,"-",now)'"

(Please use a font that distinguishes the quotation mark, ",
from the double-apostrophes, '', in the above...)

Next you simply put the JJ/DD/AA date you've read into
standard comparison format. You probably need to check
of year-2000 issues cases given the AA format. Given
the input date is read into a DCL symbol jda, something
like:

$ this_aa = F$Element(2, "/", jda)
$ If this_aa.Gts."10"
$ Then
$ this_aa = "19" + this_aa
$ Else
$ this_aa = "20" + this_aa
$ Endif
$ this_date = this_aa + "-" + -
F$Element(1, "/", jda) + "-" +-
F$Element(0, "/", jda)
$
$ If d60.Ges.this_date
$ Then
$ Write Sys$Output "He's at least 60 years old!"
$ Endif


It's a shame that DCL doesn't include an easy
way to convert to and from different time formats.
You can do that in a compiled language using
the various LIB$DT routines. Nevertheless,
it's not so hard to do "by hand" using F$Element
and friends.

-Ken

Richard B. Gilbert

unread,
Nov 11, 2009, 3:51:18 PM11/11/09
to

The string JJ/MM/AA is not used in English. Would you please be so kind
as to spell it out? Is it supposed to be Day/Month/Year? We would
abbreviate that as DD/MM/YY or, more rarely DAMOY.

Hein RMS van den Heuvel

unread,
Nov 11, 2009, 11:10:12 PM11/11/09
to
On Nov 11, 11:37 am, DTL <didier.mora...@gmail.com> wrote:
:

> I'm needing some help to write the following in DCL:
> if person's age >= 60 years old then...
> knowning that birth date in file has format JJ/MM/AA
:
> Didier

Salut Didier! Comment ca va?

So many ways to solve this.
Two major details to decide on first though
- What is the cutoff YEAR for a recorded birthday to be in the 1900s
or 2000s ?
- Is the decision to be taken for 'today', or for a particular date
this year?

In the solution below I just pretended all recorded dates are in the
1900's allowing for folks to be more than 100 years old. If the you
have reason to believe that no person can be more than for example 90
years today, then you may want to subtract 100 if you find an age >
90.
That will 'fix' folks born between 2000 and now.

The solution below uses TODAY as test date.
Use 10000*f$cvtim(,,"YEAR") if any time this years is good.

If you re-arrange the segments in 19YYMMDD format then you can just
subtract them from the current or sample date and then divide by 10000
than you will get an accurate number of years.

The plain subtraction does of course NOT render an accurate number of
days.
For example 20090101 - 20071231 is 367 days, not 18870 days but both
turn to 1 year which is correct because only 20070101 would be 2
years.

In an example procedure that gives:

$ slash = "/"
$ cutoff = 60
$loop:
$ READ /END=done/PROMPT="JJ/MM/AA: " SYS$COMMAND jjmmaa
$ yy = F$ELEM(2, slash, jjmmaa)
$ IF yy .EQS. slash THEN GOTO loop
$
$ yymmdd = 10000*(1900+yy) + 100*F$ELEM(1,slash,jjmmaa) + F$ELEM
(0,slash,jjmmaa)
$ now = F$CVTIME(,,"DATE") - "-" - "-"
$ target = cutoff - ('now' - 'yymmdd') / 10000 ! Sloppy math is good
enough for this work
$ IF target .GT. 0 THEN target = 1
$ write sys$output f$fao ("person is !0UL!0%Cexactly!1%Cless than!
%Emore than!%F !UL",target,cutoff)
$ GOTO loop
$done:
$ EXIT

$ @tmp ! Run on 11/11/09 :-)
JJ/MM/AA: 11/11/49
person is exactly 60
JJ/MM/AA: 10/11/49
person is exactly 60
JJ/MM/AA: 12/11/49
person is less than 60
JJ/MM/AA: 12/11/48
person is exactly 60
JJ/MM/AA: 12/11/47
person is more than 60

I'm sure you can take is from there!

btw... Mike, straight date subtraction as with F$DELTA_TIME is not too
useful as if requires knowing about leap years.

Cheers,
Hein

Mike Rechtman

unread,
Nov 12, 2009, 10:31:42 AM11/12/09
to

On V7.3-2
$
$ start = "28-Feb-2008 0:0:0"
$ end = "1-mar-2008 0:0:0"
$ dif = f$delta_time( start,end )
$ sho sym dif
DIF = " 2 00:00:00.00"
$
... so the lexical seems to cope with leap years (perhaps not with leap seconds)

Hein RMS van den Heuvel

unread,
Nov 12, 2009, 11:25:24 AM11/12/09
to

Yes, of course it does.
But once you have the number of days the script would need to know
whether 366 days is 1 year or 1 year plus 1 day, making the person
potentially a year older.

Hein.

FrankS

unread,
Nov 12, 2009, 1:34:20 PM11/12/09
to
On Nov 12, 10:31 am, Mike Rechtman <m...@rechtman.com> wrote:
> $ start = "28-Feb-2008 0:0:0"
> $ end = "1-mar-2008 0:0:0"
> $ dif = f$delta_time( start,end )

Try it with dates that are more than about 27 years (or 9999 days)
apart.

Mike Rechtman

unread,
Nov 12, 2009, 2:37:47 PM11/12/09
to

You're right! Didn't think of that.

$
$ start = "2-Sep-1943 0:0:0"
$ end = "12-Nov-2009 0:0:0"
$ age = f$delta( start , end )
%SYSTEM-F-IVTIME, invalid time
$

SMOP to workaround, though!

DTL

unread,
Nov 13, 2009, 10:16:40 AM11/13/09
to
well well well
:oops: I'm very sorry.
Of course, as you guessed, it was DD/MM/YY
VMS 8.3 Alpha

Now, considering the CPU time used with good old DCL and my Charon
emulator :-) I've better code that in Fortran as the file is 220 000
records big !

Thanks to all
Merci Hein, ca vax :-)

I'll post another question for the gurus now.
Bye,

DTL

Hein RMS van den Heuvel

unread,
Nov 13, 2009, 1:56:15 PM11/13/09
to
On Nov 13, 10:16 am, DTL <didier.mora...@gmail.com> wrote:
:

> Now, considering the CPU time used with good old DCL and my Charon
> emulator :-) I've better code that in Fortran as the file is 220 000
> records big !

Unless you are more comfortable with Fortran than DCL, I'd say not
worth the hassle for a tiny 200k record file.You may want to pre-read
it with search to load teh XFC cache, such that the DCL single block
IO dos not slow it down.

The only CPU intensive code in my example is the silly FAO formatting
I added just for fun.

The core algorithm is only:

$ now = F$CVTIME(,,"DATE") - "-" - "-"

:
$loop:
$read...
:
$ yymmdd = 10000*(1900+F$ELEM(2,slash,jjmmaa)) + -
100*F$ELEM(1,slash,jjmmaa) + F$ELEM(0,slash,jjmmaa)
$ IF cutoff .GT. ('now' - 'yymmdd') / 10000
$ THEN. ...
:


Cheers,
Hein.

Bax...@tessco.com

unread,
Nov 18, 2009, 3:10:18 PM11/18/09
to
On Nov 13, 1:56 pm, Hein RMS van den Heuvel

I'm kinda surprised that I haven't seen anyone mention the
"Comparison" option in f$cvtime()

i.e.

$ Time1 = f$cvtime("<first date/time>","Comparison",)
$ Time2 = f$cvtime("<second date/time>","Comparison",)

then boolian comparison can be done
$ If ( Time1 .les. Time2 ) then ...

I would imagine that a variation on this could be used to provide the
solution.

Dave

Dave

Ken Fairfield

unread,
Nov 18, 2009, 3:33:43 PM11/18/09
to
On Nov 18, 12:10 pm, Baxt...@tessco.com wrote:
[...]

> I'm kinda surprised that I haven't seen anyone mention the
> "Comparison" option in  f$cvtime()
>
> i.e.
>
> $ Time1 = f$cvtime("<first date/time>","Comparison",)
> $ Time2 = f$cvtime("<second date/time>","Comparison",)

I did...but it seems as if <some> of my posts haven't
escaped to the wild from the confines of Google Groups.
I see them, but others apparently don't. :-( See if you
(or anyone? anyone?) can find my post from Nov 11, 9:50 am.

> then  boolian comparison can be done
> $ If ( Time1 .les. Time2 ) then ...
>
> I would imagine that a variation on this could be used to provide the
> solution.

Yes. The only "tricky" part, if you even consider it to
be tricky, is the format of the input dates. I preferred to
apply a little F$Element to the problem, find the date
60 years earlier than TODAY, and then use COMPARISON
date format to make the call. Pretty straight forward, eh?

-Ken

0 new messages