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

I have wote a simple code to determine yesterday's date. I would like to return the day and month as two diget values such as 01, 02... How do I specify the type of return? thanks. -grasshopper
#!/usr/bin/perl -w #use strict; use warnings; use Date::Calc qw(:all); ($year, $month, $day) = Today(); $Dd = -1; ($year,$month,$day) = Add_Delta_Days($year,$month,$day, $Dd); $year = $year; $month = "$month"; $day = "$day"; print "$year\n"; print "$month\n"; print "$day\n"; print "$year$month$day\n";

janitored by ybiC: Properly closed unbalanced <code> tags

Replies are listed 'Best First'.
Re: Values of day and month in two digets
by jarich (Curate) on Mar 12, 2004 at 03:32 UTC
    #!/usr/bin/perl -w # use strict; use warnings; use Date::Calc qw(:all); ($year, $month, $day) = Today(); $Dd = -1; ($year,$month,$day) = Add_Delta_Days($year,$month,$day, $Dd); $year = $year; $month = "$month"; $day = "$day"; print "$year\n"; print "$month\n"; print "$day\n"; print "$year$month$day\n";

    Surely you didn't mean to comment out use strict when it's so easy to make this script strict compliant?

    my ($year, $month, $day) = Today(); my $Dd = -1;
    and that's it!

    Anyway, the answer you're looking for is sprintf.

    $month = sprintf("%02d", $month);
    This will add up to two zeros for padding to give you a 2 digit number.

    Hope this helps.

    jarich

      Thank you Jarich, this is just what I needed. I must confess that I did comment out the use of strict. Ummmm, I was getting a ton of error messages when I included strict that did not understand. For instance Global symbol "$year" requires explicit package name at ./date_calc_test.pl line 7. I am on page 67 of Learning Perl "Notes on Lexical (my) Variable". Maybe this will enlighten me! cheers, Grasshopper.
        ($year, $month, $day) = Today(); # Line 7

        Global symbol "$year" requires explicit package name at ./date_calc_test.pl line 7.

        When you're using strict you have to let Perl know what the scope of each variable is. Variables declared with the keyword "my" exist from when you declare them until the end of their current block. A block is the space between matching curly braces, or, if they are outside of all curly braces, the file.

        So in the following we have a few blocks

        # Start block 0 use strict; my $foo; # exists from here to the end of the file { # Start block 1 my $a; # exists from here to end of block 1 { # Start block 2 my $b; # exists from here to end of block 2 print $b; } # End block 2: $b stops existing here # print $b; # (would fail, no $b can be found) $a++; } # End block 1: $a stops existing here # print $a; # (would fail, no $a can be found) # print $b; # (would fail) print $foo; # successful # End of file $foo stops existing here.
        Note that the commented out prints would work if you took away "use strict". This is because Perl would ASSUME that you intended to print the value of the (non-existant) global $a or $b at the points where the lexical (declared with "my") variables didn't exist. That it doesn't exist isn't a problem, Perl will automatically bring it into existance just for you.

        This is a problem if you do something like the following:

        my @friends = ("Simon", "Howard", "Jane", "Jacinta"); print $freind[3];
        because Perl will very happily print you the third element of a non-existant list. Strict is very helpful at picking up spelling mistakes and errors like this.

        When we're using strict, Perl still assumes that variables not declared with "my" must be referring to the global ones. Global variables can be accessed from any block regardless of where (how many blocks in) they were first mentioned. They can also be accessed from outside the file. However, strict still requires you to tell it that you want variables to be global (if you do, which you probably don't). This can be done with the "our" keyword.

        As I said in my earlier post, by adding the word "my" next to the first times you used your variables your script would have become strict compliant.

        ($year, $month, $day) = Today(); # Line 7 $Dd = -1;
        becomes:
        my ($year, $month, $day) = Today(); # Line 7 my $Dd = -1;

        If you have any questions about strict, feel free to ask.

        All the best,

        jarich

Re: Values of day and month in two digets
by graff (Chancellor) on Mar 12, 2004 at 04:16 UTC
    If all you're doing is printing the result, you don't need variables at all:
    #!/usr/bin/env perl use strict; use Date::Calc qw(:all); printf "%d%.2d%.2d\n", Add_Delta_Days( Today(), -1 ); __END__
    But if you want to keep those three values around as properly formatted separate strings, you could do it this way:
    use strict; use Date::Calc qw(:all); my ( $year, $month, $day ) = map { sprintf "%.2d", $_ } Add_Delta_Days( Today(), -1 ); print join '', $year, $month, $day, "\n"; __END__
Re: Values of day and month in two digets
by pbeckingham (Parson) on Mar 12, 2004 at 05:43 UTC

    I suggest that the call to Data::Calc::Add_Delta_Days is not necessary, as subtracting 86_400 (number of seconds in a day) from time is guaranteed to yield 'yesterday', regardless of the time of day. I use:

    #!/usr/bin/perl -w use strict; my ($d, $m, $y) = (localtime (time-86_400)) [3..5]; printf "%04d%02d%02d\n", $y+1900, $m+1, $d;

      Very little in date or time handling comes with a guarantee. Consider daylight savings time or leap seconds, for example.

        Unix ignores leap-seconds (see time(2)) and (modulo leap-seconds) the time() function always works in UTC.