Perl Localtime Returning 16 Hours When Input is only Seconds
I must be doing something wrong, but I can't figure it out. When I give seconds as an argument to localtime(), I get seconds and 16 hours back.
my $startTime = time;
(process)
my $endTime = t开发者_StackOverflow中文版ime;
my $diffTime = ( $endTime - $startTime );
($sec,$min,$hour) = localtime( $diffTime );
print STDERR "diffTime = $diffTime\n";
print STDERR "hour = $hour\n";
print STDERR "min= $min\n";
print STDERR "sec = $sec\n";
print( sprintf( "Elapsed time : %02d:%02d:%02d\n", $hour, $min, $sec ) );
...always prints:
diffTime = 4
hour = 16
min= 0
sec = 4
Elapsed time : 16:00:04
OKAY. Figured out how to add comments - NoScript settings were too tight.
Thanks...
I can't seem to add comments to this thread, so I'll just thank everyone here.
NOT using gmtime was the problem. It may not be the most efficient solution, but it works for what I need, which is just a simple bit of info for the user to evaluate how long he/she might wait for the routine to complete and make decisions about how large an input dataset he/she is comfortable with.
You're mixing durations and timestamps, that's asking for trouble...
You might get away with using gmtime
, like Mansoor suggests, but still, you're using an apple as an orange.
The following works, and uses the core Time::Piece and Time::Seconds modules. For $diffTime->pretty
, you need a newer version (1.20) of Time::Piece than is bundled with current versions of Perl, though.
use strict;
use warnings;
use 5.010;
use Time::Piece 1.20;
my $startTime = localtime();
# (process)
my $endTime = localtime();
my $diffTime = ( $endTime - $startTime );
say STDERR "diffTime = ", $diffTime;
say STDERR "hours = ", $diffTime->hours; # not the same thing as above
say STDERR "minutes = ", $diffTime->minutes; # not the same thing as above
say STDERR "seconds = ", $diffTime->seconds; # not the same thing as above
say "Elapsed time: ", $diffTime->pretty;
This might print something like:
150
0.0416666666666667
2.5
150
2 minutes, 30 seconds
$difftime
is the difference between two "epoch times" (seconds since midnight GMT 1/1/1970), but that doesn't make it an epoch time. So it's not really a suitable argument for localtime()
. You're better off computing the h/m/s breakdown yourself:
($sec,$min,$hour) = ($difftime % 60, int($difftime/60) % 60, int($difftime/3600));
You want to use the gmtime
function instead of the localtime
function.
Since the epoch date is Jan. 1, 1970 00:00:00 GMT/UTC, calling localtime(0)
will give you the epoch date in your time zone.
EDIT: Thanks for the follow-ups. As has been mentioned, this only works if you're measuring an interval that is less than 24 hours. Both the localtime
and gmtime
functions actually return the values of a date: seconds, minutes, hours, day of the month, month, year, day of the year, and whether the time falls into a daylight savings period. Of course, everything beyond seconds, minutes, and hours don't make sense outside of the context of a date.
This is the same problem as saying that since ℉ → ℃ requires a conversion of C = (F - 32) * 5/9
, that if it got warmer by 5 ℉ that that must be the same as getting warmer by −15 ℃, since that’s the number you get when you just plug 5 ℉ into the obvious-but-wrong formula.
See why that makes no sense? Getting warmer by 5 ℉ is not at all the same as getting colder by 15 ℃!
You’ve made much the same error with your times. When you subtract quantities each measuring seconds elapsed since the epoch, you do not get a result that also measures seconds elapsed since the epoch!!
You can only call localtime
or gmtime
on epoch seconds, meaning on seconds elapsed since the epoch, not on seconds in general. You have to do your own dividing otherwise, or use a module, to find out how many larger units there are in the result of that subtraction.
精彩评论