Year of day in localtime and timelocal don't match?

J

J Moreno

As I read the documentation, the day of the year in both should be the
same, but when I run the script below, they differ by a day (I get the
day before the today's day as returned by localtime).

Is this a problem with the documentation, my reading of the
documentation, or a bug (i.e. do I have to check to see if the behavior
changes based upon version or something)?

###
use warnings;
use strict;

use Time::Local 'timelocal_nocheck';

$\ = "\n";

my $b;
my $day_of_year;

($b,$b,$b,$b,$b,$b,$b,$day_of_year) = localtime;

print "From localtime: " . $day_of_year;

($b,$b,$b,$b,$b,$b,$b,$day_of_year) = localtime timelocal_nocheck
(0,0,0,$day_of_year, 0, 0);

print "From localtime via timelocal_nocheck: " . $day_of_year;

###

Outputs:

From localtime: 66
From localtime via timelocal_nocheck 65
 
B

Brian Wakem

J said:
As I read the documentation, the day of the year in both should be the
same, but when I run the script below, they differ by a day (I get the
day before the today's day as returned by localtime).

Is this a problem with the documentation, my reading of the
documentation, or a bug (i.e. do I have to check to see if the behavior
changes based upon version or something)?

###
use warnings;
use strict;

use Time::Local 'timelocal_nocheck';

$\ = "\n";

my $b;
my $day_of_year;

($b,$b,$b,$b,$b,$b,$b,$day_of_year) = localtime;

print "From localtime: " . $day_of_year;

($b,$b,$b,$b,$b,$b,$b,$day_of_year) = localtime timelocal_nocheck
(0,0,0,$day_of_year, 0, 0);

^^ year 0 is equivalent to 2000

print "From localtime via timelocal_nocheck: " . $day_of_year;

###

Outputs:

From localtime: 66
From localtime via timelocal_nocheck 65


2000 was a leap year.
 
B

Brian Wakem

Gunnar said:
Not true.


According to the Gregorian calendar, which is the civil calendar in use
today, years evenly divisible by 4 are leap years, with the exception of
centurial years that are not evenly divisible by 400. Therefore, the years
1700, 1800, 1900 and 2100 are not leap years, but 1600, 2000, and 2400 are
leap years.
 
C

Ch Lamprecht

Brian said:
J Moreno wrote:
2000 was a leap year.
Hi,
did you check with 2001 ??

timelocal_nocheck expects a day_of_month as 4th param ranging from 1 to
something .
Localtime returns day_of_year ranging from 0 to 364.

Christoph
 
A

A. Sinan Unur

(e-mail address removed) (J Moreno) wrote in (e-mail address removed):
As I read the documentation, the day of the year in both should be the
same, but when I run the script below, they differ by a day (I get the
day before the today's day as returned by localtime).

Is this a problem with the documentation, my reading of the
documentation, or a bug (i.e. do I have to check to see if the
behavior changes based upon version or something)?
....

($b,$b,$b,$b,$b,$b,$b,$day_of_year) = localtime timelocal_nocheck
(0,0,0,$day_of_year, 0, 0);

$time = timelocal($sec,$min,$hour,$mday,$mon,$year);

You are passing to this function:

$sec = 0
$min = 0
$hour = 0
$mday = $day_of_year
$mon = 0
$year = 0

$day_of_year is out of range for $mday. While the docs show examples of
such usage, it also warns:

Your mileage may vary when trying these with minutes and hours, and it
doesn't work at all for months.

I guess this falls under "your mileage may vary".


D:\Home\asu1\UseNet\clpmisc> cat time.pl
use warnings;
use strict;

use Time::Local 'timelocal';

my $d1 = (localtime)[7];

print "From localtime: $d1\n";

my $d2 = (localtime timelocal(localtime))[7];

print "From localtime via timelocal: $d2\n";


D:\Home\asu1\UseNet\clpmisc> time.pl
From localtime: 66
From localtime via timelocal: 66
 
U

usenet

J said:
Is this a problem with...

FWIW, you can (and should) use more Perl-ish notation, such as:

my $day_of_year = (localtime)[7];

instead of

($b,$b,$b,$b,$b,$b,$b,$day_of_year) = localtime;
 
G

Gunnar Hjalmarsson

J said:
As I read the documentation, the day of the year in both should be the
same, but when I run the script below, they differ by a day (I get the
day before the today's day as returned by localtime).

Is this a problem with the documentation, my reading of the
documentation, or a bug (i.e. do I have to check to see if the behavior
changes based upon version or something)?

($b,$b,$b,$b,$b,$b,$b,$day_of_year) = localtime;

print "From localtime: " . $day_of_year;

From "perldoc -f localtime":
"$yday is the day of the year, in the range 0..364 (or 0..365 in leap
years.)"

Hence you need to pass $day_of_year+1 to timelocal_nocheck() to make the
8:th element returned by localtime() equal $day_of_year.

$day_of_year =
(localtime timelocal_nocheck 0,0,0,$day_of_year+1,0,0)[7];
-----------------------------------------------------^^
 
G

Gunnar Hjalmarsson

Brian said:
According to the Gregorian calendar, which is the civil calendar in use
today, years evenly divisible by 4 are leap years, with the exception of
centurial years that are not evenly divisible by 400. Therefore, the years
1700, 1800, 1900 and 2100 are not leap years, but 1600, 2000, and 2400 are
leap years.

I was wrong; sorry.

Nevertheless, that fact is unrelated to the OP's observation. See my
other post in this thread.
 
B

Brian Wakem

Gunnar said:
I was wrong; sorry.

Nevertheless, that fact is unrelated to the OP's observation. See my
other post in this thread.


No need to apologise.

I saw it was 1 day out, noticed the leap year and assumed that was the
answer, so I was wrong too.
 
J

J Moreno

Gunnar Hjalmarsson said:
From "perldoc -f localtime":
"$yday is the day of the year, in the range 0..364 (or 0..365 in leap
years.)"

Hence you need to pass $day_of_year+1 to timelocal_nocheck() to make the
8:th element returned by localtime() equal $day_of_year.

I'm clear as to what localtime returns, it's timelocal_nocheck's desired
input that I'm not so clear on.

(OK, now I see where it is sorta clear --- the first example for
timelocal_nocheck is for the 365th day of 1999, i.e. the last day of a
year without a leap day, which localtime will return as 364 but the
example shows as using 365).

To all,
Sorry about the bad example, my original example was slightly different,
changed at the last minute to "simplify" the output and make things even
more clear, and I didn't think of the year change.

Here's the orginal script:

###
use warnings;
use strict;

use Time::Local 'timelocal_nocheck';

$\ = "\n";

my $b;
my $day_of_year;
my $l_year;

($b,$b,$b,$b,$b,$l_year,$b,$day_of_year) = localtime;

print scalar localtime;

print scalar localtime timelocal_nocheck 0,0,0,$day_of_year, 0, $l_year;

###

And output...

Wed Mar 8 23:26:19 2006
Tue Mar 7 00:00:00 2006
 
A

Anno Siegel

J Moreno said:
I'm clear as to what localtime returns, it's timelocal_nocheck's desired
input that I'm not so clear on.

Read Gunnar's reply again. The day_of_year count starts at 0, the
day_of_month count starts at 1. That goes for the return values of
localtime() as well as for the input parameters of timelocal() and
timelocal_nocheck(). You are using a day_of_year type count as
a day_of_month type argument. Of course the result is off by one.

Anno
 
J

J Moreno

Anno Siegel said:
Read Gunnar's reply again. The day_of_year count starts at 0, the
day_of_month count starts at 1. That goes for the return values of
localtime() as well as for the input parameters of timelocal() and
timelocal_nocheck(). You are using a day_of_year type count as
a day_of_month type argument. Of course the result is off by one.

No, I don't think so.

###
use warnings;
use strict;

use Time::Local 'timelocal_nocheck';

$\ = "\n";

my $day_of_year;
my $l_year;

$l_year = (localtime)[5];
$day_of_year = (localtime)[7];

print "Day of year fom localtime is: $day_of_year";
print scalar localtime;
print scalar localtime timelocal_nocheck 0,0,0,$day_of_year, 0, $l_year;
print '';

print scalar localtime timelocal_nocheck 0,0,0,0, 0, 2006;
print scalar localtime timelocal_nocheck 0,0,0,15, 0, 2006;
print scalar localtime timelocal_nocheck 0,0,0,45, 0, 2006;
print scalar localtime timelocal_nocheck 0,0,0,90, 0, 2006;
print scalar localtime timelocal_nocheck 0,0,0,180, 0, 2006;
print scalar localtime timelocal_nocheck 0,0,0,360, 0, 2006;
###

Outputs...

Day of year fom localtime is: 67
Thu Mar 9 09:14:13 2006
Wed Mar 8 00:00:00 2006

Sat Dec 31 00:00:00 2005
Sun Jan 15 00:00:00 2006
Tue Feb 14 00:00:00 2006
Fri Mar 31 00:00:00 2006
Thu Jun 29 00:00:00 2006
Tue Dec 26 00:00:00 2006

So, timelocal_nocheck is clearly treating it as a day of year value,
not a day of the month value which is being liberally interpreted, and
(localtime)[7] is just as clearly (and clearly documented as) returning
the day of the year.

It's just that the two days of the year don't match up.

And as I said in the previous post, the example in Time::Local shows
that the day of the year value is 1 based (for 365 in 99 it outputs
Dec 31) for timelocal_nocheck.

Also note that it handles negative values and that the zeroth day of
the year 2006 is Dec 31, 2005.

So, to sum it up...localtime returns a zero based day of year count,
timelocal_nocheck uses a 1 based day of year count, and all of this is
there in the docs, but IMO for timelocal_nocheck it's not as clearly
stated as it could be.
 
A

Anno Siegel

J Moreno said:
No, I don't think so.

Hmmm? One count is zero based, the other is one based. When you use
one for the other, you'll be off by one. Nothing of what you wrote
contradicts that.

[...]
So, timelocal_nocheck is clearly treating it as a day of year value,
not a day of the month value which is being liberally interpreted, and

What is the difference between a liberally interpreted day of month
and a day of year? Especially if the month in question is January?

Anno
 
J

J Moreno

Anno Siegel said:
What is the difference between a liberally interpreted day of month
and a day of year? Especially if the month in question is January?

You're right, I was wrong. It was the January that set me straight,
thanks.

It is indeed a liberally interpreted day of month, with the default
month being January.

###
use Time::Local 'timelocal_nocheck';

$\ = "\n";

print scalar localtime timelocal_nocheck 0,0,0,365, 2, 2006;
###

Outputs

Wed Feb 28 00:00:00 2007

(My mental mistake was ignoring/forgetting the default values and what
they meant. Thanks for calling me on it).
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top