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

Greetings Monks, Is anyone aware of a module that would help me determine if a time in this format:
02:29:40
Falls between a start and stop time in the same format? I came up with this elementray way of converting the hours, minutes, and seconds into a number like so:
my ($ace_hour_start,$ace_min_start,$ace_sec_start) = (split/:/, $ace_start_time); $ace_hour_start = $ace_hour_start * 100; $ace_min_start = $ace_min_start * 10; $ace_start_time = $ace_hour_start + $ace_min_start + $ace_sec_start +; my ($ace_hour_stop,$ace_min_stop,$ace_sec_stop) = (split/:/, $ace_stop_time); $ace_hour_stop = $ace_hour_stop * 100; $ace_min_stop = $ace_min_stop * 10; $ace_stop_time = $ace_hour_stop + $ace_min_stop + $ace_sec_stop;
But I'm thinking there has got to be an easier/cleaner way. I looked through the plethora of Date/Time modules on CPAN and nothing is jumping out at me (but I'm sure it's right in front of me).

I appreciate any suggestions.

Replies are listed 'Best First'.
Re: Seeing if a Time is Within a Range
by blokhead (Monsignor) on Oct 26, 2004 at 18:33 UTC
    As long as all the fields are all zero-padded, the standard lexical string order is what you want. No need to do any fancy conversion, the string comparison operators will work fine:
    my $date = ...; if ( $date ge $begin and $date le $end ) { ... }

    blokhead

Re: Seeing if a Time is Within a Range
by pg (Canon) on Oct 26, 2004 at 18:34 UTC

    This looks like 24-hour hh::mm::ss format, if it is strictly followed, what's wrong with a straight 'ge', or 'le'?

    use strict; use warnings; print between('02:03:04', '02:03:01', '13:00:24'), "\n"; print between('02:03:04', '02:03:05', '13:00:24'), "\n"; print between('14:03:04', '02:03:01', '13:00:24'), "\n"; print between('14:03:04', '02:03:01', '15:00:24'), "\n"; sub between { my ($t, $begin, $end) = @_; return (($t ge $begin) && ($t le $end)); }
      Just a note of caution when implemention a "between" function. This seems obvious, but I know its bitten me a couple of times.


      Be sure you use the correct comparisons for the data your working with. You have four choices of what "between" means:
      (time >= start and time <= end)
      (time > start and time <= end)
      (time >= start and time < end)
      (time > start and time < end)

      Make sure you use the correct comparison for your application.


      E.g
      01:01:00 – event 1 happened
      01:59:00 – event 2 happened
      02:00:00 – event 3 happened
      02:01:00 – event 4 happened
      02:59:00 – event 5 happened

      Ask yourself: If you have one comparison from 01:00:00 to 02:00:00 and then a second comparison from 02:00:00 to 03:00:00, where do you want event 3 to show up? Both? First? Second? Neither?

        You are absolutely right! Just a side note, if you use SQL between operator, you have to be aware that the values specified after the BETWEEN operator are inclusive. So if you say:

        select first_name, last_name, credit_limit from customer where credit_limit between 500 and 800

        The result set will include those ones with credit limit equal to 500 or 800. If you want to exclude those people, you have to write a query like this:

        select first_name, last_name, credit_limit from customer where credit_limit > 500 and credit_limit < 800
Re: Seeing if a Time is Within a Range
by fglock (Vicar) on Oct 26, 2004 at 18:30 UTC

    You could just remove the colons and have the same effect:

    $start_time =~ s/://g;
Re: Seeing if a Time is Within a Range
by LTjake (Prior) on Oct 27, 2004 at 15:32 UTC

    You might try DateTime::Span. You can do:

    if ( $span->contains( $datetime ) ) { # ... }

    To see if it falls within "start" and "end".

    --
    "Go up to the next female stranger you see and tell her that her "body is a wonderland."
    My hypothesis is that she’ll be too busy laughing at you to even bother slapping you.
    " (src)