On Jul 2, 2011, at 4:37 PM, Peter Hicks wrote:

> All,
>
> I have a requirement to translate a time between 0000 and 2359 in to a
> single character 'interval ID' based on the time.  For example, if the
> time is between 0000 and 0059, '0' should be returned, if it's between
> 0100 and 0159, '1' should be return.  The problem is that 0700-0729
> should return 'A', 0730-0759 should return 'B', i.e. it's not a simple
> mapping.
>
> I have the following, but I can't help thinking there's a much more
> efficient way of doing it - can anyone advise, as I'm a little stuck!
>
>  xlate = [ [ '0000', '0059', '0' ], [ '0100', '0159', '1' ],
>            [ '0200', '0259', '2' ], [ '0300', '0359', '3' ],
>            [ '0400', '0459', '4' ], [ '0500', '0559', '5' ],
>            [ '0600', '0659', '6' ], [ '0700', '0729', 'A' ],
>            [ '0730', '0759', 'B' ], [ '0800', '0829', 'C' ],
>            [ '0830', '0859', 'D' ], [ '0900', '0929', 'E' ],
>            [ '0930', '0959', 'F' ], [ '1000', '1029', 'G' ],
>            [ '1030', '1059', 'H' ], [ '1100', '1129', 'I' ],
>            [ '1130', '1159', 'J' ], [ '1200', '1229', 'K' ],
>            [ '1230', '1259', 'L' ], [ '1300', '1329', 'M' ],
>            [ '1330', '1359', 'N' ], [ '1400', '1429', 'O' ],
>            [ '1430', '1459', 'P' ], [ '1500', '1529', 'Q' ],
>            [ '1530', '1559', 'R' ], [ '1600', '1629', 'S' ],
>            [ '1630', '1659', 'T' ], [ '1700', '1729', 'U' ],
>            [ '1730', '1759', 'V' ], [ '1800', '1829', 'W' ],
>            [ '1830', '1859', 'X' ], [ '1900', '1959', 'Y' ],
>            [ '2000', '2059', 'Z' ], [ '2100', '2159', '7' ],
>            [ '2200', '2259', '8' ], [ '2300', '2359', '9' ] ]
>
>  xlate.each do |range|
>    return range[2] if time >= range[0] && time <= range[1]
>  end
>
> --  
> Peter Hicks <peter.hicks / poggs.co.uk>

You just need to check from the "end" on back and pick the first one  
that matches.

  xlate = [ [ '0000', '0' ], [ '0100', '1' ], [ '0200', '2' ],  
[ '0300', '3' ],
            [ '0400', '4' ], [ '0500', '5' ], [ '0600', '6' ],  
[ '0700', 'A' ],
            [ '0730', 'B' ], [ '0800', 'C' ], [ '0830', 'D' ],  
[ '0900', 'E' ],
            [ '0930', 'F' ], [ '1000', 'G' ], [ '1030', 'H' ],  
[ '1100', 'I' ],
            [ '1130', 'J' ], [ '1200', 'K' ], [ '1230', 'L' ],  
[ '1300', 'M' ],
            [ '1330', 'N' ], [ '1400', 'O' ], [ '1430', 'P' ],  
[ '1500', 'Q' ],
            [ '1530', 'R' ], [ '1600', 'S' ], [ '1630', 'T' ],  
[ '1700', 'U' ],
            [ '1730', 'V' ], [ '1800', 'W' ], [ '1830', 'X' ],  
[ '1900', 'Y' ],
            [ '2000', 'Z' ], [ '2100', '7' ], [ '2200', '8' ],  
[ '2300', '9' ],
            ].reverse
#  Note the .reverse here

time = Time.now.strftime('%H%M')
xlate.detect{|(start,code)| time >= start}

Then you can vary the start times and not be concerned about the  
"breaks" in the mapping or whether there is a 30-minute boundary. (And  
not build an 60x24 entry string or array of minutes even though that  
might be more efficient depending on how many lookups you need to do.)

-Rob

Rob Biedenharn		
Rob / AgileConsultingLLC.com	http://AgileConsultingLLC.com/
rab / GaslightSoftware.com		http://GaslightSoftware.com/