Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

my($day, $month, $year)=(localtime)[3,4,5]; print "$day\-".$month+1."-".$year+1900."\n";

does this always work. I know it works right now, but how does it work when it gets to December. Is the value 11 and you increment one, and then the next month is 00. I am just a little confused and timid to place this in my code. Does it also work the same for the day if you +1?

thanks for any help you give

Edit Masem 2001-10-15 - CODE and P tags

Replies are listed 'Best First'.
Re: date and time
by suaveant (Parson) on Oct 16, 2001 at 00:11 UTC
    localtime outputs the month based at 0 for array lookups, so yes, adding 1 will ALWAYS give you the month number in human readable form. You cannot +1 the day, because the days go from 1-31, and on the 31st if you did +1 then it would show that tomorrow was the 32nd...

    I would suggest you look into POSIX::strftime and also the modules Date::Manip and Date::Calc

                    - Ant
                    - Some of my best work - Fish Dinner

      The 'strangeness' comes directly from the tm struct the unix routines localtime(2) and gmtime(2) use.
      Your comment about array lookups is right on. The day-of-the-week (localtime[6]) also starts at zero to facilitate lookup.
Re: date and time
by blakem (Monsignor) on Oct 16, 2001 at 00:07 UTC
    Read all about it at localtime.
    #!/usr/bin/perl -wT use strict; my $today = get_date(); my $yesterday = get_date(-1); my $tomorrow = get_date(1); print "Yesterday = $yesterday\n"; print "Today = $today\n"; print "Tomorrow = $tomorrow\n"; sub get_date { my $offset = shift || 0; my $ts = time + $offset*60*60*24; my ($day,$month,$year) = (localtime($ts))[3,4,5]; sprintf ("%02s-%02s-%04s",$day,$month+1,$year+1900); } =OUTPUT Yesterday = 14-10-2001 Today = 15-10-2001 Tomorrow = 16-10-2001

    -Blake

Re: date and time
by artist (Parson) on Oct 16, 2001 at 00:21 UTC
Re: date and time
by fokat (Deacon) on Oct 16, 2001 at 01:35 UTC
    Just to point something else out...

    Never assume that the year is a number between 0 and 99. To obtain the current year, you simply add 1900 to the value returned by timelocal(...). For today, this means that $year will be 101.

    I've had to fix a number of bugs in other people's code because of this...

Re: date and time
by mitd (Curate) on Oct 16, 2001 at 06:39 UTC
    This does seem like wee bit more trouble than its worth when Date::Format will make short work of it. But.. sigh you may have a good reason not to use a 'pm'. Hopefully that reason is not laziness because in this case it is not a programmatic virtue. A few minutes with Date::Format will allow you date and time laziness for a life time. A few more minutes spent with Date::Manip and Date::Calc will let you deal with time() while sitting under a palm tree sipping Tequila Sunrises.

    mitd-Made in the Dark
    'My favourite colour appears to be grey.'

Re: date and time
by pixel (Scribe) on Oct 16, 2001 at 12:03 UTC

    I'd do that using the POSIX::strftime function. It saves you having to worry about issues like this.

    use POSIX 'strftime'; my $date = strftime('%d-%m-%Y', localtime); print "$date\n";

    Blessed Be
    The Pixel

Re: date and time
by Stegalex (Chaplain) on Oct 16, 2001 at 07:57 UTC
    Looks like you have been into the Perl Cookbook in chapter 3 and that you have been looking at page 71. The edition I have erroneously states that the range for $yday is 1-366 (but it's really 1-365). I think that the range for $sec is also wrong (0-60 vs 0-59).

    Pay special attention to the $isdst variable. It's going to come in handy on October 28 when we "fall back".

    $isdst is important if your machine is set to Universal Time and you are processing epoch seconds that are expressed in a US time zone (Eastern for example). If you are doing date math on a UT box but using EST or EDT, you need to examine $isdst to know how many seconds to subtract.

    I have been bitten by this, but that's because I'm dumb.
      Hi Stegalex
      The edition I have erroneously states that the range for $yday is 1-366 (but it's really 1-365)

      My book shows $yday as having a range from 0-365, which gives $yday an effective max of 366. This makes sense; there are 366 days in a leap year, so the range of $yday has to be effectively 366.

      I think that the range for $sec is also wrong (0-60 vs 0-59)

      Just as we can have leap days, we can have leap seconds- though they generally get less press. ("What? You were born on a leap second? That means you have a birthday, what... every time some standards organization wants you to have one?!"). Or, couched in the slightly less facetious tones of Cookbook: The values for second range from 0-60 to account for leap seconds, you never know when a spare second will leap into existence at the urging of various standards bodies.

      blyman