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

I have a situation where I want to get the current year(4 digit),
month(2 digits), and day(2 digits).

Getting the values isn't the "challenge" for me here, it's
getting the second digit on values less than 9 for
for the month and the day.

I've written the following code which does what I want,
but I want to know what PERL has built in to do this.
I've got the O'Reilly books Learning Perl and
Programming Perl, but finding the "correct" function
is proving a challenge.

All suggestions appreciated.

use strict; use warnings; my $day = (localtime)[3]; my $month = (1..12)[(localtime)[4]]; my $year = (localtime)[5] + 1900; if(length($day) < 2){ $day = "0".$day; } if(length($month) <2){ $month = "0".$month; } print "$year$month$day\n"; exit(0);

Replies are listed 'Best First'.
Formatting Dates
by gellyfish (Monsignor) on Feb 06, 2002 at 22:01 UTC

    sprintf is the baby that you want to use - you will be able to read about that more in the documentation. But as date things are a very common use I'll repeat an example:

    use strict; use warnings; my ( $day, $month, $year ) = (localtime)[3,4,5]; my $date = sprintf "%.04d%.02d%.02d", $year + 1900, $month + 1, $day;

    I'm sure this code has been shown thousands of time before

    /J\

Re: Seeking the
by Bepa (Beadle) on Feb 06, 2002 at 21:46 UTC
    You will want to use sprintf() to make sure the month is always two digits.

    This is Bepa
Re: Seeking the
by rjray (Chaplain) on Feb 06, 2002 at 22:44 UTC

    Based on your updated reply saying that you aren't planning on printing them, I can only assume you are using them for string comparisons. Otherwise, the presence of the leading zero would be meaningless in a numeric comparison. (And no, it wouldn't cause evaluation as octal.)

    Also, like one other person showed, it would be much more efficient to get $month and increment it, rather than subscripting a constant array as you are in your sample code.

    Getting back to your question, there are two ways to produce the strings you want:

    ($day, $month, $year) = (localtime)[3 .. 5]; $year += 1900; # Method 1: $day = sprintf "%02d", $day; $month = sprintf "%02d", $month + 1; # Method 2: $day = substr("0$day", -2); $month++; $month = substr("0$month", -2);

    As you can see, printf is still you best tool here, though strictly-speaking you are using its cousin sprintf.

    --rjray

Re: Seeking the
by Spudnuts (Pilgrim) on Feb 06, 2002 at 23:39 UTC
    I prefer to use the POSIX function strftime. An example of this would be:
    use strict; use warnings; use POSIX qw(strftime); print strftime("%Y%m%d", localtime()), "\n";
    Here are descriptions of the format flags. The man page is from FreeBSD, but most of the flags are standards-compliant, so it's pretty much a moot point.

    I find this preferable because it requires significantly fewer lines of code and reuses library functionality.

Re: Seeking the
by data64 (Chaplain) on Feb 07, 2002 at 01:54 UTC

    If converting to string is all the date manipulation you are doing, then sprintf is probably good enough. If you are doing more involved computation, look at Date::Business.

Re: Seeking the
by Parham (Friar) on Feb 07, 2002 at 00:37 UTC
    Just a bit off topic...

    Correctly speaking, sprintf() and printf() are probably the better solution. But it seems that you're unfamiliar with those and more comfortable concatinating leading zeros. There is absolutely nothing wrong with the way your doing things, there is always more than one way to do things and your way seems just as good as any other.

    to answer your question though:
    $day = 5; #test variable $month = 7; #test variable $day = sprintf("%02d",$day); $month = sprintf("%02d",$month); print "$day\n$month";
    would print:
    05
    07
Re: Seeking the
by Rpick (Novice) on Feb 06, 2002 at 22:25 UTC
    OOPS,

    My code's not a good example.

    I was using it to see what happened to the values of the
    variables, and I think the wrong impression was given.

    These values probably will not be printed.
    If I can get this to work they will be used for a comparison.
    Probably something I should be using a regular expression for,
    but I'm just getting started and regexs are still
    a bit incomprehensible.

    I need the leading 0 on the month and day if they are less
    than 9 and the value will not be printed, so
    although I thank you for your answers I don't think
    sprintf will work.

      No, sprintf is exactly what you want - it formats into a string without printing

      Please refer to the perlfunc manpage for more details.

      /J\