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

Discussion in 'Perl Misc' started by J Moreno, Mar 8, 2006.

  1. J Moreno

    J Moreno Guest

    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



    --
    John Moreno
    "Everything is futile." -- Marvin of Borg
     
    J Moreno, Mar 8, 2006
    #1
    1. Advertising

  2. J Moreno

    Brian Wakem Guest

    J Moreno wrote:

    > 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.


    --
    Brian Wakem
    Email: http://homepage.ntlworld.com/b.wakem/myemail.png
     
    Brian Wakem, Mar 8, 2006
    #2
    1. Advertising

  3. Brian Wakem wrote:
    > J Moreno wrote:
    >>
    >>($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


    True.

    > 2000 was a leap year.


    Not true.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Mar 8, 2006
    #3
  4. J Moreno

    Brian Wakem Guest

    Gunnar Hjalmarsson wrote:

    > Brian Wakem wrote:
    >> J Moreno wrote:
    >>>
    >>>($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

    >
    > True.
    >
    >> 2000 was a leap year.

    >
    > 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.



    --
    Brian Wakem
    Email: http://homepage.ntlworld.com/b.wakem/myemail.png
     
    Brian Wakem, Mar 8, 2006
    #4
  5. J Moreno

    Ch Lamprecht Guest

    Brian Wakem wrote:
    > J Moreno wrote:
    >
    >
    >>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).


    >>###
    >>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;
    >>


    >
    > 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


    --

    perl -e "print scalar reverse q//"
     
    Ch Lamprecht, Mar 8, 2006
    #5
  6. (J Moreno) wrote in news:1hbw3qt.mwmbb31c2hn32N%
    :

    > 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

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Mar 8, 2006
    #6
  7. J Moreno

    Guest

    J Moreno wrote:
    > 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;

    --
    http://DavidFilmer.com
     
    , Mar 8, 2006
    #7
  8. J Moreno wrote:
    > 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)?


    <snip>

    > ($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];
    -----------------------------------------------------^^

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Mar 8, 2006
    #8
  9. Brian Wakem wrote:
    > Gunnar Hjalmarsson wrote:
    >>Brian Wakem wrote:
    >>>2000 was a leap year.

    >>
    >>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.


    I was wrong; sorry.

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

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Mar 8, 2006
    #9
  10. J Moreno

    Brian Wakem Guest

    Gunnar Hjalmarsson wrote:

    > Brian Wakem wrote:
    >> Gunnar Hjalmarsson wrote:
    >>>Brian Wakem wrote:
    >>>>2000 was a leap year.
    >>>
    >>>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.

    >
    > 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.


    --
    Brian Wakem
    Email: http://homepage.ntlworld.com/b.wakem/myemail.png
     
    Brian Wakem, Mar 8, 2006
    #10
  11. J Moreno

    J Moreno Guest

    Gunnar Hjalmarsson <> wrote:

    > J Moreno wrote:
    > > 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)?

    >
    > <snip>
    > > ($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.


    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

    --
    JM
    "Everything is futile." -- Marvin of Borg
     
    J Moreno, Mar 9, 2006
    #11
  12. J Moreno

    Anno Siegel Guest

    J Moreno <> wrote in comp.lang.perl.misc:
    > Gunnar Hjalmarsson <> wrote:
    >
    > > J Moreno wrote:
    > > > 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)?

    > >
    > > <snip>
    > > > ($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.

    >
    > 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
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Mar 9, 2006
    #12
  13. J Moreno

    J Moreno Guest

    Anno Siegel <-berlin.de> wrote:

    > 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.

    --
    JM
    "Everything is futile." -- Marvin of Borg
     
    J Moreno, Mar 9, 2006
    #13
  14. J Moreno

    Anno Siegel Guest

    J Moreno <> wrote in comp.lang.perl.misc:
    > Anno Siegel <-berlin.de> wrote:
    >
    > > 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.


    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
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Mar 9, 2006
    #14
  15. J Moreno

    J Moreno Guest

    Anno Siegel <-berlin.de> wrote:

    > J Moreno <> wrote in comp.lang.perl.misc:

    -snip-
    > > 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?


    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).

    --
    JM
    "Everything is futile." -- Marvin of Borg
     
    J Moreno, Mar 9, 2006
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andy
    Replies:
    1
    Views:
    743
  2. Rob Redmon

    Convert day of year to month, day

    Rob Redmon, Apr 4, 2008, in forum: Ruby
    Replies:
    7
    Views:
    324
    Alex Wayne
    Apr 4, 2008
  3. yocoyote

    Bug in timelocal?

    yocoyote, Apr 6, 2005, in forum: Perl Misc
    Replies:
    14
    Views:
    182
    Joe Smith
    Apr 7, 2005
  4. Datamon
    Replies:
    1
    Views:
    104
  5. John
    Replies:
    2
    Views:
    116
Loading...

Share This Page