http://qs1969.pair.com?node_id=145107

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

the script below does not return the date correctly, can you tell me what I am doing wrong? Thank you.
#!/usr/bin/perl ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); $date = "$month/$mday/20$year"; print ("$date\n");
My biggest issue is with the year. It appends a '1' to the date, so it looks like this: 20102

Edit Masem 2002-02-13 - Added code tags

Title edit by tye as single-word titles complicate future simple searches

Replies are listed 'Best First'.
Re: date
by snowcrash (Friar) on Feb 13, 2002 at 08:31 UTC
    the biggest issue is that you should "read the fine manual". try perldoc -f localtime for a start. the year localtime returns is an offset of years that have passed since 1900. also, try to put your code inside a <code> tag, that will enhance readability a lot.

    thanks,
    snowcrash
Re: date
by demerphq (Chancellor) on Feb 13, 2002 at 09:38 UTC
      For those that are a bit uneasy with using POSIX, Date::Format has a compatible strftime().

      I'm not quite sure what little is on about below, with other languages, and Apache... =/
      But Date::Format (or POSIX::strftime) is definitely what you're looking for.

        Date::Format allows to say as an Option for example 'german'

        Date::Format->language('German');

        which causes a format of like "%A, den %d. %B %Y" to display as 'Mittwoch, den 13. Februar 2002'
        And thats just noted in the POD. So simply change this option to english and you get the date in english, ok, there you need to provide a different Format though. But could it be any easier than this?

        Have a nice day
        All decision is left to your taste
Re: date
by little (Curate) on Feb 13, 2002 at 11:07 UTC
    Take a look at Date::Format which is comliant with the timefmt string that apache takes in AND also has some kind of language packs so you get the short and long names for days and monts in many languages, so yours might be there as well. If you don't need that "language feature" think about the possibility of others reusing your code and the effort then to adapt it to other languages.

    Have a nice day
    All decision is left to your taste
      If you don't want to use Date::Format and don't care that your code might be 'internationalised', here's a snippet of code that I continually reuse:
      sub library_todayis { my ($time)=@_; if ($time<1) { $time=time(); } my @months=qw!Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec!; my ($sec, $min, $hour, $day, $mon, $year, $dweek, $dyear, $tz) = loca +ltime($time); if ($day<10) { $day="0".$day; } if ($hour<10) { $hour="0".$hour; } if ($min<10) { $min="0".$min; } if ($sec<10) { $sec="0".$sec; } $year = $year + 1900; return ("$day $months[$mon] $year $hour:$min"); }
      Pass it the timestamp you want converting (or leave blank for the current time), and in return you'll get something like 13 Feb 2002 18:48 in your current timezone.

      Update: Thanks to little, for a 'duh! why are you doing it like that?' here's a shortened version doing it the slightly better way using sprintf:

      sub library_todayis { my $time=shift || time(); my @months=qw!Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec!; my ($sec,$min,$hour,$day,$mon,$year)=localtime($time); $year+=1900;$mon++; return sprintf("%02d $months[$mon] $year %02d:%02d",$day,$hour,$min); }
      Which, I have to confess is a lot better looking and probably a bit faster (although I haven't benchmarked it)
        But you've heard about printf or sprintf or POSIX?
        Those would shorten this your code by 50% up to 80%. *grin*
        And you don't need to install them cause they are where Perl is.

        Have a nice day
        All decision is left to your taste
Re: date
by beebware (Pilgrim) on Feb 13, 2002 at 16:31 UTC
    #!/usr/bin/perl ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); $year+=1900; $date = "$month/$mday/$year";

    Add the $year+=1900; line, the year is number of years since 1900.
      Your month value will be off by one (did you test this code?), as the value returned is designed to be used as an offset into an array of month names. Thus, if today is the 14th February 2002, your $date will contain "1/14/2002".

      Where possible, one should try to avoid regional date formatting styles, and use the ISO 8601 norm, to whit, "2002/02/14". The date 2/6/2002 can be parsed as either 2nd of June or 6th of February, depending on which part of the world you live in.

      In Perl 6, this odd behaviour will be corrected, insofar as the year value will be returned as 2002, not 102. Something to keep in mind. Off hand, I remember the month value as also being fixed (hence 2 for February).

Re: date
by buckaduck (Chaplain) on Feb 14, 2002 at 01:55 UTC
    $date = "$month/$mday/20$year";
    Wow. Hardcoding the digits '20' in the year. Have people forgotten about Y2K already? I can see a whole new era of Y3K failures on the horizon...

    "Why does my Perl program say 'Jan. 1, 201100' instead of 'Jan. 1, 3000'?"

    Hopefully, I'll be dead by then. I'd hate to go through all of that again.

    buckaduck