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

Good day Monks!

So I am using this code that works perfectly on a website.

On the website it displays 0d 1h 17m 43s, days hours minutes and seconds for how long that process ran for.

But I used a similiar code to print "Duration : 0d 0h 5m 0s" every 5 minutes to show how long the process has been running so they know when they want to stop.

For some reason, once it hits 1 hour, it doesn't print "Duration : 0d 1h 0m 0s", instead it prints "Duration : 0d 0h 0m 0s".

The .cgi and .pl uses the same code to convert the time so I have no idea why it doesn't show the hour..

while (1) { my $days = int($runtime / 86400); $runtime -= ($days * 86400); my $hours = int($runtime / 3600); $runtime -= ($hours * 3600); my $minutes = int($runtime / 60); my $seconds = $runtime % 60; $days = $days .'d '; $hours = $hours .'h '; $minutes = $minutes .'m '; $runtime2 = $runtime; $runtime2 = $days . $hours . $minutes . $seconds . 's'; if (time()>=$nextruntime){ $nextruntime=time()+300; $runtime += 300; print "Duration: $runtime2\n"; }

Code used for the .cgi

my $epochrun = $epochend - $epochstart; my $days = int($epochrun / 86400); $epochrun -= ($days * 86400); my $hours = int($epochrun / 3600); $epochrun -= ($hours * 3600); my $minutes = int($epochrun / 60); my $seconds = $epochrun % 60; $days = $days .'d '; $hours = $hours .'h '; $minutes = $minutes .'m '; $epochrun = $days . $hours . $minutes . $seconds . 's';

Thanks in advance!

This just finished printing...

Starting iostat-10-test-2014_06_30-09:57:35_EDT Starting vmstat-10-test-2014_06_30-09:57:35_EDT Duration: 0d 0h 0m 0s Starting mpstat-10-test-2014_06_30-09:57:35_EDT Duration: 0d 0h 5m 0s Duration: 0d 0h 10m 0s Duration: 0d 0h 15m 0s Duration: 0d 0h 20m 0s Duration: 0d 0h 25m 0s Duration: 0d 0h 30m 0s Duration: 0d 0h 35m 0s Duration: 0d 0h 40m 0s Duration: 0d 0h 45m 0s Duration: 0d 0h 50m 0s Duration: 0d 0h 55m 0s Duration: 0d 0h 0m 0s

Replies are listed 'Best First'.
Re: Timestamp doesn't work well
by kennethk (Abbot) on Jun 30, 2014 at 15:38 UTC
    First, are you sure you've accurately transcribed the code you are running? If I run
    #!/usr/bin/perl -w use strict; my $runtime = 3600; my $runtime2; my $nextruntime = 0; my $days = int($runtime / 86400); $runtime -= ($days * 86400); my $hours = int($runtime / 3600); $runtime -= ($hours * 3600); my $minutes = int($runtime / 60); my $seconds = $runtime % 60; $days = $days .'d '; $hours = $hours .'h '; $minutes = $minutes .'m '; $runtime2 = $runtime; $runtime2 = $days . $hours . $minutes . $seconds . 's'; if (time()>=$nextruntime){ $nextruntime=time()+300; $runtime += 300; print "Duration: $runtime2\n"; }
    I get the output
    Duration: 0d 1h 0m 0s
    which corresponds with your spec but not your cited output. However, on the next iteration of your loop, I would get
    Duration: 0d 0h 5m 0s
    This issue happens because you are dropping hour and above information on every iteration of your loop. You need to choose if you are going to destructively parse your term, or use it as an accumulator. You'll have better luck with something like:
    #!/usr/bin/perl -w use strict; my $start = time(); while (1) { my $buffer = (time() - $start); ($buffer, my $seconds) = (int $buffer/60, $buffer % 60); ($buffer, my $minutes) = (int $buffer/60, $buffer % 60); ($buffer, my $hours) = (int $buffer/24, $buffer % 24); my $days = $buffer; print "Duration: ${days}d ${hours}h ${minutes}m ${seconds}s\n"; sleep (300); }

    As a side note, while(1) is incredibly abusive to system resources as you've implemented it. Take a look at sleep for implementing waiting in a script.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Ah wow thanks! Yeah your code makes perfect sense for this situation.. and I didn't think about the sleep part either.. ahahah
Re: Timestamp doesn't work well
by stonecolddevin (Parson) on Jun 30, 2014 at 16:25 UTC

    Use DateTime. It's got an absolute wealth of pre-existing logic and a gargantuan test suite covering all of these things and more.

    Three thousand years of beautiful tradition, from Moses to Sandy Koufax, you're god damn right I'm living in the fucking past