Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Determining time since

by Anonymous Monk
on Jan 12, 2004 at 14:52 UTC ( [id://320669]=perlquestion: print w/replies, xml ) Need Help??

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

The script below works well enough for my liking, but I was wondering if there was an easier way to go about this. I have a saved time which I am subtracting from time() to see how long ago (in seconds) the event happened. From that, I tried to calculate into minutes, then into hours, then into days. I was also wondering if there was a more percise way of going about this.

This is setup to calculate minutes UNTIL it's greater than 60, then automatically calculate hours. How can I make it calculate hours and minutes at the same time? And how could I get it so I could see how many days and hours it was? (I don't mean if it was 27 hours ago that the script would say 1 day(s) 27 hour(s), I'd want it to say 1 day(s) 3 hour(s)).

my $time=time; my $elapsed = $time - $oldtime; if ($elapsed < "60") { print "<td><center>< 1 min</center></td></tr>\n"; } elsif ($elapsed > "60") { my $newelapsed = $elapsed / 60; my $elapsed2 = substr( $newelapsed, 0, 2 ); print "<td><center>$elapsed2 min(s)</center></td></tr>\n"; } elsif ($elapsed > "3600") { my $newelapsed = $elapsed / (60*60); my $elapsed2 = substr( $newelapsed, 0, 2 ); print "<td><center>$elapsed2 hour(s)</center></td></tr>\n"; } elsif ($elapsed > "43200") { my $newelapsed = $elapsed / (60*60); my $elapsed2 = substr( $newelapsed, 0, 2 ); print "<td><center>$elapsed2 day(s)</center></td></tr>\n"; } }

Any suggestions would be very grateful.

Replies are listed 'Best First'.
Re: Determining time since
by duff (Parson) on Jan 12, 2004 at 15:03 UTC

    I have a few of comments:

    • You shouldn't stringify your numbers. $elapsed > 3600 works just fine thanks.
    • You should separate your "chopping up time" logic from your presentation logic. I'd write a subroutine that does what you need to an elapsed-time value and returns an array of seconds, minutes, hours, etc.
    • Have you checked CPAN? I'm fairly sure there's already a module that does this (though I've not had occasion to use it).

    As to a better way than your method, you might want to use integer division and modulo arithmetic:

    $days = int($time/86400); $time %= 86400; # leave only the part that's less than a d +ay $hours = int($time/3600); $time %= 3600; # leave only the part that's less than an +hour; ... # and so on

      Along the same lines, you could do something to the effect of

      Update: After reading sulfericacid's response, I tested my algo. The issue was a typo ( popped up with use strict;), and I wasn't calling int. New code below.

      #!/usr/bin/perl # tested and verified use strict; my $then = time() - (86400 * 3); my $min_s = 60; my $hour_s = $min_s * 60; my $day_s = $hour_s * 24; my $elapsed = time() - $then; my $output; my $days = int( $elapsed / $day_s ); $elapsed -= $days * $day_s; $output = "$days days " if $days; my $hours = int ( $elapsed / $hour_s ); $elapsed -= $hours * $hour_s; $output .= "$hours hours " if $hours; my $mins = int ( $elapsed / $min_s ); $elapsed -= $mins * $min_s; $output .= "$mins minutes " if $mins; $output .= "$elapsed seconds" if $elapsed; # so on and so forth; print "$output ago\n";

      use perl;
      Everyone should spend some time pounding nails with their forehead for a while before they graduate to complicated stuff like hammers. - Dominus

        I tried l2kashe's code and the test came out:
        0.00146257716049383 days 4.21062361931911e-18 hours ago
        I have no idea what went wrong, but I think you should go with a module on this one. Check out Time::Duration from cpan.org. It looks like it'll accomplish this for you.


        "Age is nothing more than an inaccurate number bestowed upon us at birth as just another means for others to judge and classify us"

        sulfericacid
Re: Determining time since
by Art_XIV (Hermit) on Jan 12, 2004 at 19:40 UTC

    Here's an example using a CPAN module:

    use warnings; use strict; use Date::Calc qw(Delta_DHMS Localtime); my @start_date = qw(1965 11 06 09 32 00); my @now = (Localtime())[0..5]; my ($days, $hrs, $mins, $secs) = Delta_DHMS(@start_date, @now); print "There have been $days days, $hrs hours, "; print "$mins minutes, $secs seconds since my birth.\n"; 1;
    Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"
Re: Determining time since
by Anonymous Monk on Jan 12, 2004 at 15:01 UTC
    Okay, I just ran into a problem. I thought my script was right but obviously there is an error in there somewhere. My script has just now come across a time that's over an hour old and instead of converting into hours, it prints "64 minute(s) ago". What am I doing wrong?
      Your tests are in the wrong order. Check them in descending order, not increasing order. >60 will not fall through to >3600, because anything that's >3600 is >60.

      The PerlMonk tr/// Advocate

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://320669]
Approved by Zaxo
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-20 00:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found