in reply to getting answer 70 years off

G'day derekstucki,

Your main problem is that "my $age = (localtime ( time - $time ))[5];" is not doing what you presumable imagine it does. Consider the following which assumes an age of 25:

$ perl -Mstrict -Mwarnings -E ' my $x = time; say $x; my $y = int($x - (25*365.24225*24*60*60)); say $y; my $z = (localtime($x-$y))[5]; say $z ' 1389999563 601076303 95

That's out by 70. Using ages of 5 and 45 gives 75 and 115 respectively: i.e. out by 70 also. You added the comment "# localtime returns years since 1900": you took this into consideration with your first localtime() (i.e. ... + 1900) but ignored it with the second. The epoch started in 1970: that's 70 years since 1900. Had you added 1900 for $age, then substracted 1970, you would have got the right answer: obviously that's ridiculously complicated. Here's a much easier way to do it:

#!/usr/bin/env perl -l use strict; use warnings; use Time::Piece; use Time::Seconds; my @YMDs = ([2004, 1, 17], [2004, 1, 18], [2004, 1, 19]); my $now = localtime; print 'Now: ', $now->strftime('%Y-%m-%d'); for (@YMDs) { my $dob = Time::Piece->strptime(join('-' => @$_), '%Y-%m-%d'); print 'DOB: ', $dob->strftime('%Y-%m-%d'); print 'Age: ', int(($now->epoch - $dob->epoch) / ONE_YEAR); }

Output:

Now: 2014-01-18 DOB: 2004-01-17 Age: 10 DOB: 2004-01-18 Age: 10 DOB: 2004-01-19 Age: 9

You also have problems in your regex:

You also have problems in your validation (if( $mon < 0 or ...); for instance, 31st February would be considered valid!

-- Ken

Replies are listed 'Best First'.
Re^2: getting answer 70 years off
by derekstucki (Sexton) on Jan 21, 2014 at 20:52 UTC
    Oh, I can't believe I forgot to put the '-' at the end of the group, thanks for that. As for not needing to escape the '/', I'm afraid you're mistaken, at least for perl 5.14.2. I just tested it, and it doesn't compile: "Unmatched [ in regex;", and vim's highlighting ends the regex there, which in my opinion is reason enough to include it, even if it is unnecessary and benign. I did intend for that group to match one or more times, as some people may put spaces around their '\/-' ( sounds stupid, but there's a lot of stupid out there, and I try to account for all of it that I can ), but thanks for pointing it out.
      "As for not needing to escape the '/', I'm afraid you're mistaken, at least for perl 5.14.2. I just tested it, and it doesn't compile: "Unmatched [ in regex;", ..."

      I'm currently using 5.18.1 but also have 5.14.2 available: I can't reproduce the error you report:

      $ perlbrew switch perl-5.14.2 $ perl -v This is perl 5, version 14, subversion 2 (v5.14.2) ... $ perl -Mstrict -Mwarnings -e 'my $re = qr{[ /\\-]}' $ perlbrew switch perl-5.18.1t $ perl -v This is perl 5, version 18, subversion 1 (v5.18.1) ... $ perl -Mstrict -Mwarnings -e 'my $re = qr{[ /\\-]}'

      The perlrecharclass link I provided was for 5.18.0. The perlrecharclass documentation for 5.14.2 has the same information.

      "... and vim's highlighting ends the regex there, which in my opinion is reason enough to include it, even if it is unnecessary and benign."

      I also use vim with syntax highlighting. I find it has many problems, particularly with regular expressions. I don't change my code to fit in with vim's problems.

      -- Ken

        Ah, if you write your regexes that way ( "qr{...}" ), then you wouldn't need to escape them, but when you use " /.../ " notation, they do have to be escaped, or else they end the regex. TMTOWTDI. Vim highlights both of these cases accurately in my limited testing.

        $ perl -Mstrict -Mwarnings -e 'my $re = /[ /\\-]/' Unmatched [ in regex; marked by <-- HERE in m/[ <-- HERE / at -e line + 1.