Conal has asked for the wisdom of the Perl Monks concerning the following question:

This script runs twice every hour at both 00mins15secs and 30mins15secs. I am trying to select the nearest time before the 30min or 00min but NOT AFTER from an input file that can look like this.
//SNAGIT.TXT eg top of the hour 1.29133 ,01:59:34 1.29132 ,01:59:59 1.29132 ,01:59:59 .....
desired pair - 1.29132 ,01:59:59
//SNAGIT.TXT e.g bottom of the hour 1.29020 ,01:29:52 1.29036 ,01:30:02 1.29035 ,01:30:12 ....
desired pair - 1.29020 ,01:29:52

the code i have come up to achieve this is below, (i need the pattern matching regex to filter out dirty data.)
use Time::ParseDate; use Time::Local; ... my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdist) = localtime +time; my $month = (qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)) [(lo +caltime)[4]]; my $day = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[(localtime)[6]]; $year = $year+1900; my $input = "SNAGIT.txt"; my $actualquote1=0; ## Open the SNAGIT.TXT, plus some sensible error checking open(DATAFILE, "$input") || die("Can't open $input:!\n"); ## Loop through the file one line at a time while (<DATAFILE>) { chomp; if ( m{^ (\d\.\d{5}) \s*,\s* (\d\d:\d\d:\d\d) \s* (.*) $ }x ) ## 1.XXXXX { my ( $quote, $linetime, $comment ) = ( $1, $2, $3 ); # captures my ( $snaghour, $snagminute, $snagsecond ) = split /:/, $linetime; + chop($quote); if (parsedate($snaghour.":".$snagminute.":".$snagsecond) <= parsed +ate($hour.":".$min.":00")) { $actualquote1 = $quote; } } } close(DATAFILE);
Now my problem is; The code works great when the script runs on the 30minute, $actualquote gets assigned as it should.

The issue is the 00 script run, $actualquote never gets assigned the value i would expect, it remains assigned to 0.

can anyone suggest what the issue is?

i have mulled over this problem for a while and came up with a really ugly hacked solution previously.

I am rewriting my code now and i am sure this type of approach is cleaner.

thanks for reading and i hope i make some sense.
conal.

Replies are listed 'Best First'.
Re: Time::ParseDate issues
by eye (Chaplain) on Nov 27, 2008 at 07:06 UTC
    When the script runs at the top of the hour ("00"), the value for $min is 0. Have you verified that parsedate() isn't bothered by a time that looks like "2:0:00"?

    In any case, this:

    parsedate($hour.":".$min.":00")
    could be replaced with $now after adding the following lines before the while:
    my $now = time; $now -= ($now % 60);
      The parsedate function will return undef value, if the time format is not correct.
      The time format is hh:mm:ss.
      You can add the digit zero in front of hour and minute.
      You can use the following code:
      $min = "0".$min if(length($min) == 1); $hour= "0".$hour if(length($hour) == 1);
      hi eye, thanks for replying with this. i have tried a number of solutions here and yours seems the most likely. fixing up $hour and $min so it is in a format that doesnt make Parsedate return undef still produces an issue at 00:00:00. i have a problem tho, what is this code doing exactly and why does it work?
      my $now = time; $now -= ($now % 60);
      and also would it work if i wanted to run my code every 5minutes with similar data, as opposed to 30minutes? thanks for your input and sorry to be a pain.
      conal.
        parsedate($hour.":".$min.":00"))

        should give the same number of seconds,(since Jan 1, 1970), as:

        my $now = time; $now -= ($now % 60);

        I say should because I don't know if the function parsedate gives seconds since the epoch when only supplied the time numbers (and not the date numbers).

        What his code is doing is removing any seconds (> 00)

        Chris

Re: Time::ParseDate issues
by Anonymous Monk on Nov 27, 2008 at 03:31 UTC
    The issue is the 00 script run, $actualquote never gets assigned the value i would expect, it remains assigned to 0.
    can anyone suggest what the issue is?

    Add this to your code
    ... chomp; warn " \$_ ($_) "; ... warn " \$quote ($quote) \$linetime ($linetime) \$comment ($comment) ";