i was playing around with POSIX qw{strftime};
to use as uptime for a program and i found something i didn't know why it happend. I don't use time that much, this was the reason i was messing with it (learning to fill "time" :P)
the math gives me | uptime: 01:00:00
where i should be 00:00:00
I put in the line
$stop_secs = $stop_secs - "3600";
and "fixed" it, but I wonder where that extra hour came from.
i have no clue why, can anyone explain this or why this happens? thanks.
#!/usr/bin/perl
#
use strict;
use warnings;
use POSIX qw{strftime};
my $start_secs = time();
my $start_time = strftime '%H:%M:%S', localtime $start_secs; # all is: "%Y-%m-%d %H:%M:%S"
my $stop_secs = time();
$stop_secs = $stop_secs - "3600"; #<--- this fix the 1h "bug"?
my $diff_secs = $stop_secs - $start_secs;
my $diff_time = strftime '%H:%M:%S', localtime $diff_secs;
print "
| Time started: $start_time
| uptime: $diff_time
\n";
localtime($seconds)
returns the information about the local date-time corresponding to $seconds
seconds past Midnight, Jan 1st, 1970, UTC (1970-01-01T00:00:00Z), ignoring leap seconds.
So let's say that a machine uses Europe/Paris as its time zone. When it was 0 seconds past 1970-01-01T00:00:00Z, the local time would have been 1970-01-01T01:00:00+01:00. On such a machine, you therefore get 01:00:00
.
#!/usr/bin/perl
use feature qw( say );
use POSIX qw( strftime );
say strftime("%Y-%m-%dT%H:%M:%S%z", localtime(0)) =~ s/(?=..\z)/:/r;
say strftime(" %H:%M:%S", localtime(0));
$ TZ=Europe/Paris ./a
1970-01-01T01:00:00+01:00
01:00:00
$ TZ=America/Montreal ./a
1969-12-31T19:00:00-05:00
19:00:00
You shouldn't be using localtime
. You could use gmtime
to some extent.
#!/usr/bin/perl
use feature qw( say );
use POSIX qw( strftime );
say strftime("%Y-%m-%dT%H:%M:%SZ", gmtime(0));
say strftime(" %H:%M:%S", gmtime(0));
$ TZ=Europe/Paris ./b
1970-01-01T00:00:00Z
00:00:00
$ TZ=America/Montreal ./b
1970-01-01T00:00:00Z
00:00:00
But really, you shouldn't even be using strftime
since that's for date-times, not durations. It will work, but only an extent.
strftime("%H:%M:%S", gmtime($secs))
will work for durations up to but not including 24*60*60 seconds.strftime("%d:%H:%M:%S", gmtime($secs))
will work for durations up to but not including 31*24*60*60 seconds, if you're ok with representing a day as having 24 hours.