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

Hi.

I've got a date in the format of mm/dd/yyyy (ie: 10/24/2000) and need to write a function that will calculate the day before that date (ie: 10/23/2000).

Is there a simple way to do this in perl? Or will I have to code a whole 'calculation' routine?

Thanks,
Ralph.

Replies are listed 'Best First'.
Re: Calculating 1-day-before
by silent11 (Vicar) on Feb 15, 2002 at 20:50 UTC
    Have you tried Date::Calc? update
    this should work
    use Date::Calc qw(:all); $date= '10/24/2000'; $MM = substr($date,0,2); $DD = substr($date,3,2); $YYYY= substr($date,6,4); $Dd = -1; ($year,$month,$day) = Add_Delta_Days($YYYY,$MM,$DD, $Dd); $prev_day = join('/',$month,$day,$year); print "$prev_day";
Re: Calculating 1-day-before
by Kanji (Parson) on Feb 15, 2002 at 23:00 UTC

    And if you want to stick to modules that are included in the Perl core (so no trip to CPAN), you can accomplish this with Time::Local's timelocal and POSIX's fab-oo strftime ...

    use Time::Local; use POSIX qw/ strftime /; my $today = '10/24/2000'; my $days_ago = 1; my $yesterday = do { my($m,$d,$y) = split( m'/' => $today ); # I use 12 as the hour here, so there's no # confusion about daylight savings. my $t = timelocal( 0, 0, 12, $d, $m - 1, $y - 1900 ); $t -= $days_ago * 24*60*60 ; strftime( '%m/%d/%Y' => localtime($t) ); }; print "$today $yesterday";

    Looks a lot like the Time::Piece (alt.) example, no? :)

        --k.


Re: Calculating 1-day-before
by lachoy (Parson) on Feb 15, 2002 at 20:54 UTC

    Take a look at some of the date modules, including Date::Calc or even Class::Date. An example of the latter would look like:

    use strict; use Class::Date; my ( $m, $d, $y ) = split( '/', '10/24/2000' ); my $d = Class::Date->new([ $y, $m, $d ]); my $before = $d - '1D'; print "Day before: $before";

    Chris
    M-x auto-bs-mode

Re: Calculating 1-day-before
by blakem (Monsignor) on Feb 15, 2002 at 21:34 UTC
    Time::Piece is the wave of the future....
    #!/usr/bin/perl -wT use strict; use Time::Piece; my $date = "10/24/2000"; my $daysago = 1; my $format = "%m/%d/%Y"; my $newdate = ( Time::Piece->strptime( $date, $format ) - $daysago * 24*60*60 ) ->strftime($format); print "$date - $daysago => $newdate\n"; __END__ 10/24/2000 - 1 => 10/23/2000

    -Blake

Re: Calculating 1-day-before
by data64 (Chaplain) on Feb 15, 2002 at 20:53 UTC
Re: Calculating 1-day-before
by TStanley (Canon) on Feb 15, 2002 at 21:01 UTC
    This will do what you want:
    ($d,$m,$y)=(localtime((time-60*60*(12+(localtime)[2]))))[3,4,5];


    TStanley
    --------
    "Suppose you were an idiot... And suppose you were a
    member of Congress... But I repeat myself." -- Mark Twain

      That will break for time zones that use daylight savings time. On the days where the clock is set back an hour, you will not be subtracting enough from time() to make that work. Better to use Date::Calc, as suggested elsewhere in this thread.

Re: Calculating 1-day-before
by runrig (Abbot) on Feb 16, 2002 at 06:54 UTC
    Using Super search and looking for things like 'yesterday' turns up alot of good ideas, similar to those posted again here :-)
Re: Calculating 1-day-before
by Anonymous Monk on Feb 16, 2002 at 02:17 UTC
    Hi.
    Thanks for all of your replies! :)

    In the end I went with Kanji's approach since it uses core Perl modules and I'm running on a shared server.

    Still, I'd be interested in knowing how TStanley's code works. Cause I see this complex line of code, but can't really understand what each thing does.
    ($d,$m,$y)=(localtime((time-60*60*(12+(localtime)[2]))))[3,4,5];
    Thanks,
    Ralph :)

    Edit 2/16/02 dws to add <code> tags

      Let's dissect it:

      time-60*60*(12+(localtime)2)
      That piece is taking the current time and subtracting enough seconds to get to the previous day, accounting for any daylight savings time differences. Since you don't care about the time -- just the date -- that trailing part ((12+(localtime)2)) is just taking you back 12 hours before the start of the current day. A safe way to eliminate daylight savings time issues when only a date is needed. All of this is based on the fact that time() deals with the epoch, which is expressed in seconds: 12 hours times 60 minutes per each hour times 60 seconds per each minute yields the total number of seconds 12 hours before the start of the current day. Let's let this entire result be represented by X.
      ($d, $m, $y) = (localtime(X))3,4,5;

      Is then getting the day/month/year from the calculated epoch time, represented above as X.