### Re^3: Check if Date interval contains Hour X

by alexm (Chaplain)
 on Jul 23, 2009 at 20:08 UTC ( #782777=note: print w/replies, xml ) Need Help??

The very first thing that came to my mind after reading the OP was the method DateTime::Span::contains. However, yours is the right approach since that method only works for sets that are fully inside, as the manual says.

Thanks!

Replies are listed 'Best First'.
Re^4: Check if Date interval contains Hour X
by ikegami (Pope) on Jul 23, 2009 at 20:26 UTC
contains wouldn't work, but intersects would
```...| 20 | 21 | 22 | 23 | 00 | 01 | 02 | 03 |...
(------------)     log
(----]   hour
(--)     intersection

You're right again, I just realized a bit later so I've been playing with intersects:

```sub hour_in_range {
my (\$dt_s, \$dt_e, @hours) = @_;

my \$dt_span = DateTime::Span->from_datetimes(
start => \$dt_s, end => \$dt_e
);

for my \$hour (@hours) {
my \$dt = \$dt_s->clone()
->truncate( to => 'day' )

\$dt->add( days => 1 ) if \$dt < \$dt_s;

my \$hour_span = DateTime::Span->from_datetimes(
start => \$dt, end => \$dt
);

return 1 if \$dt_span->intersects(\$hour_span);
}

return 0;
}

It's not as simple and efficient as your approach, but it shows how to use span intersection.

OTOH, I misunderstood the OP and was thinking that @hours = (1,11) was an interval (1am to 11am), not a list of hours to match.

```        my \$hour_span = DateTime::Span->from_datetimes(
start => \$dt, end => \$dt
);

should be

```        my \$hour_span = DateTime::Span->from_datetimes(
start => \$dt, before => \$dt->clone()->add( hours => 1 ),
);

```        my \$hour_span = DateTime::Span->new(
start => \$dt, hours => 1,
);

Update: No, neither fix help. They were suppose to make the following match:

```2010-10-10 01:59:59|2010-10-10 01:59:59|blablalblabla

You need

```sub hour_in_range {
my (\$dt_s, \$dt_e, @hours) = @_;

my \$dt_span = DateTime::Span->from_datetimes(
start => \$dt_s, end => \$dt_e
);

for my \$hour (@hours) {
my \$dt = \$dt_s->clone()
->truncate( to => 'day' )

my \$dt_tomorrow = \$dt->clone()->add( days => 1 );

my \$hour_span = DateTime::Span->new(
start => \$dt, hours => 1
)->union( DateTime::Span->new(
start => \$dt_tomorrow, hours => 1
));

return 1 if \$dt_span->intersects(\$hour_span);
}

return 0;
}

And there you go, the four DateTimes per hour I mentioned earlier.

Create A New User
Node Status?
node history
Node Type: note [id://782777]
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2018-06-19 22:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Should cpanminus be part of the standard Perl release?

Results (115 votes). Check out past polls.

Notices?