http://qs1969.pair.com?node_id=545456

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

Hi monks,

I have subroutine which gets two params
PARAM1 -> <time_stamp> Ex:200504250946
PARAM2 -> <interval> Ex:15 || 30 only

%normalise_with_this = ( 15 => { 00 => [ 0 .. 14 ], 15 => [ 15 .. 29 ], 30 => [ 30 .. 44 ], 45 => [ 45 .. 59 ] }; 30 => { 00 => [ 0 .. 29 ], 30 => [ 30 .. 59 ] }; );
The function has to extract the minutes from time_stamp (i,e) substr("200504250946",10,2) which results '46' from the example.
Interval is passed as 15.
from the hash "%normalise_with_this" using interval value I have to acess the first level of hash that is 15 or 30,
in our case I have to access 15.
From this I am able to access the second level of hash with the keys '00','15','30','45'.
In any of the values '46' will be there. In our case key '45' contains, 46 in it. (i,e) "45 .. 59 ".
How to point this efficiently using the above inputs which comes as a param to a function.
So function has to return the key 45.
If minute is 34, then function has to retun 30. because 34 lies in 30 => " 30 .. 44 ".

"Keep pouring your ideas"

2006-04-25 Retitled by holli, as per Monastery guidelines
Original title: 'Ideas requested from all monks members'

Replies are listed 'Best First'.
Re: Round time to nearest 15 or 30 minutes
by atcroft (Abbot) on Apr 25, 2006 at 03:52 UTC

    Just how tied to the hash are you? Assuming you have a function call such as: myfunc($ts, $interval), then something like the following might also be worth considering:

    sub myfunc { my ($ts, $interval) = @_; my $minute; # # Somehow get $minute from $ts, # using the method of your choice. # # Ex., using the method in the OP... $minute = substr($ts, 10, 2); return $interval * int($minute / $interval); }
    as it appears to provide the same results you seek, but perhaps with a little less brain-damage....

    Hope that helps.

      Hi

      Thanks a lot.
      definitely I have to improve my logical Ideas.
      That is working fine as expected.

      "Keep pouring your ideas"
        If you want the nearest 15 minute boundary, then the code is wrong. It will give you the previous 15 minute boundary.

        You need to:

        • add $interval/2 minutes to the time;
        • subtract the remainder you'd get when dividing by $interval minutes.

        Note that the modulus operator % only works with integers. In practice, you can probably ignore the fraction of a minute that gets thrown away. If you can't, then you'll need to write your own remainder function.

Re: Round time to nearest 15 or 30 minutes
by l.frankline (Hermit) on Apr 25, 2006 at 04:41 UTC

    This will also do for you:

    %normalise_with_this = ( 15 => { 00 => [ 0 .. 14 ], 15 => [ 15 .. 29 ], 30 => [ 30 .. 44 ], 45 => [ 45 .. 59 ] }, 30 => { 00 => [ 0 .. 29 ], 30 => [ 30 .. 59 ] } ); &dofunc("200504250946",15); sub dofunc { my ($interval, $pos) = @_; $min = substr($interval,10,2); foreach $v (keys %{$normalise_with_this{$pos}}) { for (@{$normalise_with_this{$pos}{$v}} ) { print $v if grep /$min/,$_; } } }

    Don't put off till tomorrow, what you can do today.