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

Hi Monks and Monkesses.

Am using Date::Calc in a Booking applic. Clients apply, date gets written etc... (usual stuff) and the booking date gets written in "yyyymmdd hh:mm" format to a flat file db.

Once the Admin confirms the booking, that time/date also gets written in the same format.

I've got a simple "Statistics" box in the Admin's area, and one of the stats I'd like to display is the average time taken between booking and confirmation, not on an individual booking basis, but for the whole lot of bookings.

I hope I've simplified things (for the server) by writing only relavent data to a "totals-to-date" file (again flat file db - one line/booking) upon the Admin "Confirming" the booking.

That data includes the booking_date|confirmation_date|time_diff|... etc. The time_diff data is in the format "days:hours:mins" (forget the secs! :-/ )

The only thing I can think of at the moment is to use Date::Calc to convert (somehow?!?) this data for each record into seconds, add up the seconds for each booking, then divide by the total number of confirmed bookings and then back again into days, hours & minutes once all data has been read, and then to display it in the Statistics box.

Is this the "right" way? (right/wrong - easy/difficult - all relative!!!) Does Date::Calc (v5.3) have a function to do this sort of thing? If I have to go the "convert to seconds" route, would this put an un-necessary load on the server ("totals-to-date" db file should not exceed 1000 records - but you never know!!!) ?

Any opinions obviously appreciated. By the sheer amount of time/date related stuff I've come across, manipulating times/dates appears to be something of a black art.

Kind regards from Andorra.
Richard.

Replies are listed 'Best First'.
Re: Calculating the average time taken..
by liz (Monsignor) on Aug 24, 2003 at 15:15 UTC
    These types of calculations usually use something called Unix epoch (the number of seconds since midnight UTC Jan 1st, 1970).

    Check out POSIX, particulary mktime() to convert the time info in your format to Unix epoch. Then you can just take time differences in seconds. Use localtime should you want to convert back again. Since you're only interested in differences, that may not be important to you.

    Many, many applications use epoch time internally as a timestamp. The reason: it simply (still) fits in a 4-byte integer and calculations on it are easy. This will all go well until somewhere early 2038. No doubt we will something of a Y2K scare again around then... ;-)

    Hope this helps.

    Liz

Re: Calculating the average time taken..
by CombatSquirrel (Hermit) on Aug 24, 2003 at 15:34 UTC
    How about
    #!perl use strict; use warnings; use Date::Calc qw(:all); sub parseTime { # gets years to mins from call, 0 for seconds added Mktime(($_[0] =~ /^(\d{4})(\d{2})(\d{2}) (\d{2}):(\d{2})$/), 0); } sub rearrangeTime { my ($in, $secs, $mins, $hours, $days, $months, $years) = (shift); $secs = $in % 60; $in = int($in / 60); $mins = $in % 60; $in = int($in / 60); $hours = $in % 24; $in = int($in / 24); $days = $in % 30; $in = int($in / 30); # EVERY month has 30 da +ys :) $months = $in % 12; $years = int($in / 12); return "$days:$hours:$mins"; } my @dates = ('20030822 15:13', '20030824 14:12'); @dates = map { parseTime $_ } @dates; my $diff = $dates[1] - $dates[0]; $diff = int($diff/2); print $diff; print $/; print rearrangeTime $diff;
    I would consider that a not-too-difficult approach. But in the end, it all depends on you anyways ;-).
    Cheers, CombatSquirrel.