Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
You just need Time::Local, the % operator, and the ability to write a little data driven code. Here is the idea:
use strict; use Time::Local qw(timelocal); sub get_time { my $date_time = shift; if ($date_time =~ /(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/) { my ($year, $mon, $day, $hour, $min, $sec) = ( $1, $2, $3, $4, $5, $6); # Months are 0-based in this API. $mon =~ s/^0//; $mon--; return timelocal($sec, $min, $hour, $dd, $mm, $yyyy); } else { die "Invalid time '$date_time'"; } }
Input a date, and you have a time in seconds. What do you do with it? Well you want to make it the time from a known moment in time that is at a known point versus the calendar. What moment? Well looking at my calendar, Jan 1, 2000 was a Saturday. So one time you could subtract is get_time("20000101000000"). OK, now we have seconds from the start of a Saturday, how do we find where you are in the week? Well % is the mod operator, that lets you find the remainder when one number is divided by another:
my $sec_in_week = (get_time($date_time) - $base_time)%(60*60*24*7);
This gives you what second you are in a week. But now what do you do with this?

Well you can build a couple of lookup arrays. One has seconds. The other parallel array has what bucket you're in. Like this:

my $base_time = get_time("20000101000000"); my @time_start; my @time_bucket; # We start at the beginning of the weekend. push @time_start, 0; push @time_bucket, "weekend"; # Monday starts with the 3rd. push @time_start, get_time("20000103000000") - $base_time; push @time_bucket, "19-7"; # Now fill in the week. for $day (3..7) { my $date = "2000010$day"; # 7 AM push @time_start, get_time($date . "070000") - $base_time; push @time_bucket, "7-9"; # 9 AM push @time_start, get_time($date . "090000") - $base_time; push @time_bucket, "9-18"; # 6 PM push @time_start, get_time($date . "180000") - $base_time; push @time_bucket, "18-19"; # 7 PM push @time_start, get_time($date . "190000") - $base_time; push @time_bucket, "19-7"; } push @time_start, get_time("20000108000000") - $base_time; push @time_bucket, "next week";
And now what you'll do is take your time mod 60*60*24*7 (the number of seconds in a week), and look in the @time_start array to find what is the last array position that is less than or equal to your time. What you then do is figure out how much of the duration goes to that bucket, increment time to the start of the next bucket, and decrement your remaining duration by the time tracked. Then look at the next time slot. When you manage to assign all of your remaining duration, you're done. If you ever get to "next week", then subtract off 60*60*24*7 from your time, go to index 0, and keep going.

What this strategy does is moves a lot of logic out of if conditions, into the setting up of the data structures.

In reply to Re: Sorting Call durations into Timeframes by tilly
in thread Sorting Call durations into Timeframes by ultibuzz

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    [hippo]: So if you don't drink as much milk and not as often you are said to drink less milk on fewer days. Confusing, eh?
    [Eily]: same as many/much, few/little
    [Discipulus]: so my 'less' usage sounded not so correct? 'fewer' was more appropriate? i take a note too
    Discipulus $ENV{PAGER}='fewer '
    [Corion]: Discipulus: Hahahaa! ;)
    [Corion]: This would be a great April fools joke, since it certainly makes sense to show fewer pages on screen :)
    [marioroy]: greetings all

    How do I use this? | Other CB clients
    Other Users?
    Others drinking their drinks and smoking their pipes about the Monastery: (5)
    As of 2018-01-23 09:12 GMT
    Find Nodes?
      Voting Booth?
      How did you see in the new year?

      Results (242 votes). Check out past polls.