As for the overall approach, I'm with ikegami (with some minor alterations): in order to make this workable in a general way, what you really want is a subroutine that takes three args: a targeted hour, and the start and end date/time values to test. A little sanity checking on the data would be worthwhile as well, and in case it counts for anything, there are some short-cuts you can take advantage of...
#!/usr/bin/env perl use strict; use Date::Calc qw/Date_to_Time/; sub hour_in_span { my ( $hr, $bgn, $end ) = @_; return unless ( $hr =~ /^\d{1,2}$/ and $hr >= 0 and $hr <= 23 ); my $hr2 = sprintf( "%02d", $hr ); # make sure to use 2 digits for ( $bgn, $end ) { return unless ( /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/ ); } return unless $bgn le $end; # require that args be in correct seq +uence # easiest case: start == end == hour of interest if ( $bgn eq $end ) { return ( $bgn =~ / $hr2:/ ); } # next easiest: span from start to end >= one full day # so it must include hour of interest my $ep_bgn = Date_to_Time( split /\D/, $bgn ); my $ep_end = Date_to_Time( split /\D/, $end ); return 1 if (( $ep_end - $ep_bgn ) / ( 24 * 60 * 60 ) >= 1 ); # hardest case: # -- plug hour of interest into each endpoint of the span # and see if either resulting time stamp falls within the span ( my $test_bgn = $bgn ) =~ s/ \d{2}:/ $hr2:/; ( my $test_end = $end ) =~ s/ \d{2}:/ $hr2:/; my $test_ep_bgn = Date_to_Time( split /\D/, $test_bgn ); my $test_ep_end = Date_to_Time( split /\D/, $test_end ); return (( $ep_bgn <= $test_ep_bgn and $ep_end >= $test_ep_bgn ) or ( $ep_bgn <= $test_ep_end and $ep_end >= $test_ep_end )); } ## End of algorithm ## -- from here on down, we're just testing it my @hours = ( 1, 11 ); while (<DATA>) { next unless ( /^\d{4}-/ ); my ( $bgn, $end ) = split /\|/; for my $hr ( @hours ) { my $in = hour_in_span( $hr, $bgn, $end ); if ( !defined( $in )) { print "$bgn -- $end / $hr : bad data\n"; } elsif ( $in ) { print "$bgn -- $end / contains $hr\n"; } else { print "$bgn -- $end / does NOT contain $hr\n"; } } } __DATA__ Start_Time | End Time | TEXT 2009-07-22 08:00:00|2009-07-22 08:00:00|blablalblabla 2009-07-22 01:00:00|2009-07-22 01:00:00|blablalblabla 2009-07-22 08:00:00|2009-07-22 21:00:00|blablalblabla 2009-07-22 23:00:00|2009-07-23 00:00:00|blablalblabla 2009-07-22 23:00:00|2009-07-23 02:00:00|blablalblabla
(BTW: you could relax the constraint on having the subroutine args in a specified order. So long as the "targeted hour" arg is in the right place, the other two args are interchangeable; just use the lower value as $bgn and the higher one as $end.)
In reply to Re: Check if Date interval contains Hour X
by graff
in thread Check if Date interval contains Hour X
by gulden
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |