Birthday Calculation

Hi I have a simple question.
Is there an easy way to read a date of birth from a file and calculate how old that person is based on today's date? And would I need the make sure the birthdates are enterered in a particular format?
Thanks

You might have to take a look at datecalc script from the forum.

A sample to calculate the age with a given date, adapt it to read the date from a file or if you have a different date format.

#!/bin/sh

echo -n "Enter the birthdate (mm-dd-yyyy): "
read bdate

bmonth=${bdate:0:2}
bday=${bdate:3:2}
byear=${bdate:6:4}

cdate=`date +%m-%d-%Y`

cmonth=${cdate:0:2}
cday=${cdate:3:2}
cyear=${cdate:6:4}

if [[ "$cmonth" -lt "$bmonth" ]] || [[ "$cmonth" -eq "$bmonth" && "$cday" -lt "$bday" ]]
then
  let age=cyear-byear-1
else
  let age=cyear-byear
fi

echo "Age = "$age

Regards

The -n option to echo is not standard.

That is not sh syntax; it is limited to bash and ksh.

Simpler (and POSIX compliant) is:

eval "$( date "+cyear=%Y cmonth=%m cday=%d" )"

[[ ... ]] is not sh syntax. Use [ .. ].

let is not standard. Use POSIX arithmetic:

age=$(( $cyear - $byear - 1 ))

This will run in any POSIX shell:

## Accept input on command line, or read interactively if none
case $# in
  3) bday=$1; bmonth=$2; byear=$3 ;;
  *) printf "Enter the birthdate (day month year): "
     read bday bmonth byear
     ;;
esac

## Ensure 2 digits for $bmonth and $bday
case $bmonth in ?) bmonth=0$bmonth;; esac
case $bday in ?) bday=0$bday;; esac

eval "$( date "+cyear=%Y cmonth=%m cday=%d" )"

[ $bmonth$bday -lt $cmonth$cday ] &&
 age=$(( $cyear - $byear )) ||
  age=$(( $cyear - $byear - 1 ))

echo "Age = $age"

]
Afraid it is supported by IEEE 1003.1:2004. Under shell command language reserved words section:

Reserved words are words that have special meaning to the shell
.....
The following words may be recognized as reserved words on some implementations (when none of the characters are quoted), causing unspecified results:

[[  ]]    function    select

......

No, It is neither supported nor required. In fact, it's behaviour is not even specified.

A POSIX shell is not required to support it, and if it does, it could do anything at all, including erase the contents of you hard drive.

I agree with fpmurphy. [[ ]] is supported in Posix and required though I personally have only found it useful in the context of "while [[ condition ]]".

[[ and ]] are keywords with strict syntax rules. A keyword starts a command and should not be used in the wrong context or be quoted (or you can get unpredictable results).

[ and ] are commands. (On early unix they were executables).

More importantly.
What goes between [[ and ]] is a "conditional expression" with one set of syntax.
What goes between [ and ] is a simple "test" with a simpler syntax. See "man test" where it you'll see that [ ] is an equivalent to "test".

The two syntaxes are covered in the man page for a Posix shell. As it happens some of the basic syntax is common between the two types of condition giving the (wrong) impression that the syntax is always interchangable.

The big syntax difference is with boolean expressions.

BTW. fpmurphy script gives syntax errors with both Posix sh and ksh because the substring variables are from bash. I'm not convinced that the line starting "if [[" will give the right result either (not tested).

Please reread the section of the POSIX specification that was posted. It says that a POSIX shell may implement [[, but it is not required to. Therefore there is no guarantee that a POSIX shell will support it, and indeed there are POSIX-compliant shells that do not support it.

For those shells that do support it, POSIX says absolutely nothing about what it should do. That's what "unspecified results" means. It could legitimately do anything at all, including wipe your hard drive.

Their rules are specified only by the shells that implement them.

[ is a command that is builtin to all modern shells, and on all POSIX systems, it also an executable. It is synonymous with test, which is also both a builtin and an executable.

] is not a command.

And that syntax is specified only by the shells that implement it; it is not defined in the POSIX specs.

Yes, they are covered in the shell's documenation only; in the POSIX specs the behaviour of [] is unspecified.

For a POSIX shell that does not support [], see /bin/sh on *BSD systems or ash or dash on Linux.

Thanks for the help, I didnt realise it was that simple. I had a really bad cold when I was trying to work it out :slight_smile:

Well, the original poster did not say the solution had to be "strict POSIX compliance" so much of the discussion below is academic at best.

This is correct, POSIX does not require the implementation of []

The only required reserved words are:

!
{
}
case
do
done
elif
else
esac
fi
for
if
in
then
until
while

There is a white paper on the Open Group website which states:

However this is at odds with the wording of the actual specification.