Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Sorting Call durations into Timeframes

by ultibuzz (Monk)
on May 08, 2009 at 15:42 UTC ( #762857=perlquestion: print w/replies, xml ) Need Help??
ultibuzz has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,
Im in need to do a report of calls per Timeframe, i will give some Infos what i mean.

what i have is the start time and the duration

Examples: format is yyyyddmmhh24miss;seconds

Based on that data i need to put the duration in propper Timeframes, the Frames are:

The Result should look like this

Start Time7-99-1818-1919-7weekend

The duration should be sorted to the Timeframes, and if a call is on a weekend but going into a monday,
then the rest of the duration need to be sorted as well.

Im at the Beginning of writing the script,
i would Go with Date::Calc for the date calculations and a while duration > 0 loop with alot of IF's to split the duration into the propper slots.

A hint how to make it better is much aprechiated

kd ultibuzz

Replies are listed 'Best First'.
Re: Sorting Call durations into Timeframes
by tilly (Archbishop) on May 09, 2009 at 00:15 UTC
    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.

Re: Sorting Call durations into Timeframes
by JavaFan (Canon) on May 08, 2009 at 16:03 UTC
    You're not showing any code, so it's hard to say how it could be improved.

    But I wonder what you will be sorting? And why?

      there is no code yet because im just starting, but asking for hints before running with alot of if's ia a good thing i think, ther e might me a sort modul someone knows or so ;)

      and im sorting the duration of the call into the timeslots, needed for buying new hardware to know exactly where the most calls are.
Re: Sorting Call durations into Timeframes
by bichonfrise74 (Vicar) on May 08, 2009 at 23:01 UTC
    I don't fully understand your question, but I'm guessing that you might need Number::Range to take care of the number calculation, Date::Calc for the dates and HoA to store the data.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://762857]
Approved by almut
[Corion]: vedagiri89: Either what choroba said, or maybe you misspelled some module name (on Windows), like use Strict; or something like that.
[vedagiri89]: @choroba, what to do for that
[Corion]: Ah, you are not on Windows, so disregard my opinion.
[vedagiri89]: in centos, how to fix this.
[choroba]: You have to find out why it happened. Was there an OS update?
[vedagiri89]: that is what i can't getting solution
[vedagiri89]: recently purchased centos server and doing migration of app
[choroba]: did you copy any dependencies?

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (13)
As of 2018-06-19 11:21 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (113 votes). Check out past polls.