Unexpected results from localtime

D

Daniel

I'm getting unexpected results from localtime. The runtime of my
programm is about 4 seconds but I'm expecting more so I'm having it
report how long it took. I reduced the code to the minimum and still
get the unexpected result. Perhaps you can help. Here is the code:

use strict;
use warnings;
my $now=time();
print scalar localtime($now), "\n";
sleep 4;
print scalar localtime(time()-$now), "\n";

That should result in printing todays date and time and then 4 seconds
after midnight january 1st 1970. but the printout gives one hour more.

Wed Nov 16 17:32:49 2005
Thu Jan 1 01:00:04 1970

It's a Windows XP Pro machine with perl 5.8.7 from ActiveState.

I'm in Germany so I've got GMT+1, but that shouldn't show.

So whats going on here?

Daniel Cutter
print chr--$g+ord for'KWVX%GUW]RP^-^Tb]2[UXa\j#'=~m$.$g;
 
L

Lars Kellogg-Stedman

print scalar localtime(time()-$now), "\n";
That should result in printing todays date and time and then 4 seconds
after midnight january 1st 1970. but the printout gives one hour more.

Why are you even doing this? Why not just print out the elapsed number
of seconds? Or use something like Time::Duration:

use Time::Duration;

my $start_time = time();
sleep 4;
print "Runtime: ", duration_exact(time() - $start_time), "\n";

For a longer running process, this would print something like:

Runtime: 2 hours, 25 minutes, and 44 seconds

-- Lars
 
D

Daniel Cutter

I'm in Germany so I've got GMT+1, but that shouldn't show.

I expect two calls to time() within 4 seconds to both be within the same
time zone. But I did mention the fact because it is, even if I can't see
a connection, a possibility.

Daniel Cutter

print chr--$g+ord for'KWVX%GUW]RP^-^Tb]2[UXa\j#'=~m$.$g;
 
A

A. Sinan Unur

I expect two calls to time() within 4 seconds to both be within the
same time zone.

Of course they are. What you are missing is the most basic of facts. The
difference between the two calls to time is probably the number 4 which
is four seconds after the epoch (probably 00:00:00 UTC, January 1,
1970).

What is the equivalent of that in your time zone? Why would you think,
when the epoch is specified relative to a specific time zone, the
interpretation of a delta from the epoch would not depend on the time
zone in which localtime is called?

If I remember the original issue, you are trying to report the run time
of your program. Why not report the number of seconds it took, or the
start versus end times? Why are you trying to interpret a time delta as
a date?

I am very puzzled.

Sinan
 
D

Daniel Cutter

print scalar localtime(time()-$now), "\n";
Why are you even doing this? Why not just print out the elapsed number
of seconds? Or use something like Time::Duration:

use Time::Duration;

my $start_time = time();
sleep 4;
print "Runtime: ", duration_exact(time() - $start_time), "\n";

For a longer running process, this would print something like:

Runtime: 2 hours, 25 minutes, and 44 seconds

-- Lars

Believe it or not: I do it that way because that is the way I've allways
done it - on all platforms with all languages. Basicly you're doing the
same in your example.

Daniel Cutter

print chr--$g+ord for'KWVX%GUW]RP^-^Tb]2[UXa\j#'=~m$.$g;
 
A

A. Sinan Unur

Believe it or not: I do it that way because that is the way I've
allways done it - on all platforms with all languages. Basicly you're
doing the same in your example.

So, you are saying that all your programs printed something like

D:\Home> tt
The program took: Wed Dec 31 19:00:04 1969

"Elapsed time" is a change in time, not a given date.

Sinan
 
L

Lars Kellogg-Stedman

allways done it - on all platforms with all languages. Basicly you're
A superb programmer *and* a sense of humor. Excellent!

-- Lars
 
A

A. Sinan Unur

A superb programmer *and* a sense of humor. Excellent!

Are you talking about me, or the OP?

Consider using an unchanging identifier in the From: header, and use the
expiring email address in the Reply-To: header only. That way, I can plonk
you once and be done with it.

Sinan
 
U

usenet

Daniel said:
I'm getting unexpected results from localtime. The runtime of my
programm is about 4 seconds...

Perl keeps track of the time your program started in the variable $^T
(or $BASETIME if you use::English).

So you can simply do:

#!/usr/bin/perl
use strict; use warnings;

sleep 4;
print time - $^T;
__END__
 
D

Daniel Cutter

#!/usr/bin/perl
use strict; use warnings;

sleep 4;
print time - $^T;
__END__

Thanks everyone for your help. I had of course only used localtime()
here for testing. I would have later replaced it with sprintf() to
format it nicely in German. I'll use the suggested $^T instead of
time(). That should then deliver the correct result.

Daniel Cutter

print chr--$g+ord for'KWVX%GUW]RP^-^Tb]2[UXa\j#'=~m$.$g;
 
B

Brian Wakem

Daniel said:
Thanks everyone for your help. I had of course only used localtime()
here for testing. I would have later replaced it with sprintf() to
format it nicely in German. I'll use the suggested $^T instead of
time(). That should then deliver the correct result.


Measuring time in whole seconds is a bit crude if you ask me. I prefer
greater precision.


$ perl -MTime::HiRes=gettimeofday,sleep -e '$start =
gettimeofday();sleep(rand);printf "%.3f seconds\n",gettimeofday()-$start'

0.633 seconds
 
B

Bart Lateur

Daniel said:
The runtime of my
programm is about 4 seconds but I'm expecting more so I'm having it
report how long it took.

Don't depend on localtime(), that's much too coarse. Use the module
Time::HiRes instead.

use Time::HiRes 'time'; # overrides the builtin
my @t = time;
sleep 4;
push @t, time;
printf "My program took %.3f seconds to run.\n", $t[1]-$t[0];

I reduced the code to the minimum and still
get the unexpected result. Perhaps you can help. Here is the code:

use strict;
use warnings;
my $now=time();
print scalar localtime($now), "\n";
sleep 4;
print scalar localtime(time()-$now), "\n";

That should result in printing todays date and time and then 4 seconds
after midnight january 1st 1970. but the printout gives one hour more.

Wed Nov 16 17:32:49 2005
Thu Jan 1 01:00:04 1970

It's a Windows XP Pro machine with perl 5.8.7 from ActiveState.

I'm in Germany so I've got GMT+1, but that shouldn't show.

But it should. time==4 is for 4 seconds after midnight Jan 1st 1970, in
GMT, *not* in your localtime.

So the solution is simple: use gmtime(time()-$now) instead of localtime.

BTW have a look at strftime() in the module POSIX, too. It's a
formatting function, related to (s)printf, to format times and dates.
 
A

Alan J. Flavell

Daniel wrote: [...]
my $now=time();
print scalar localtime($now), "\n";
[...]

So the solution is simple: use gmtime(time()-$now) instead of
localtime.

I can't resist mentioning that "$now" is an inappropriate
choice of variable name for this.

("$then" ?).
 
I

Ingo Menger

Daniel said:
Thanks everyone for your help. I had of course only used localtime()
here for testing. I would have later replaced it with sprintf() to
format it nicely in German. I'll use the suggested $^T instead of
time(). That should then deliver the correct result.

Daniel Cutter

You had the correct result already - the number 4 interpreted as that
much seconds from Jan 1st 1970, 0am UTC (or 1. Januar 1970, 01:00:00
CET), that is 01 Jan 1970 01:00:04 CET.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top