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

Dear Monks,

Hi! I need some help with a date problem. I need a way to get the current date, subtract two weeks (14 days) from it, and get a real date. So for instance, if the current date is 1/1/2002, I should get 12/18/2001 as my end result. The way the dates are formatted (12/18/2001 vs. December 18, 2001 vs. 20011218, etc) doesn't particularly matter; I can adjust that as needed.

Replies are listed 'Best First'.
Re: Subtracting Dates
by Abigail-II (Bishop) on Jun 07, 2002 at 15:04 UTC
    Use Date::Calc or Date::Manip.

    Abigail

Re: Subtracting Dates
by davorg (Chancellor) on Jun 07, 2002 at 15:47 UTC

    I really don't understand why people insist on reaching for Date::Foo modules so quickly. Both Date::Calc and (especially) Date::Manip are overkill for this problem.

    To get the time two weeks ago, simply subtract the relevant number of seconds from the current time. You can then convert that into a human-readable value using localtime or (even easier) POSIX::strftime.

    use POSIX 'strftime'; my $then = time - (14 * 24 * 60 * 60); my $date = strftime ('%Y%m%d', localtime $then); print $date; # prints 20020524

    You can easily change the format of the date returned by changing the format string passed to strftime.

    If you simply must use a CPAN module, then take a look at Time::Piece.

    use Time::Piece; use Time::Seconds; my $now = localtime; # Now a Time::Piece object my $then = $now - (14 * ONE_DAY); print $then->ymd; # or various other output functions
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Does that work with the daylight saving time rules for all the timezones in the world? And are you sure it's always going to work? Daylight saving time rules aren't static, they keep changing.

      Your method is also going to fail for dates after 2038 on many platforms (and for other dates on other platforms).

      Abigail

      Let me warn about Time::Piece. At this moment I know about at least two serious bugs in this module. I have submited bug reports to Matts but there is no fixed version yet.

      --
      Ilya Martynov (http://martynov.org/)

      Why is Date::Calc overkill? It's an appropriate solution to the problem, it doesn't pollute your namespace, and it has a very nice well-documented interface. Sure, it may take an extra 5 hundredths of a second to load the module, but it's worthwhile to have more readable code IMHO.
        Because it's not part of the standard perl distribution and I'd like to be able to distribute my code to people who don't know how/don't want to be bothered to install stuff off CPAN?

        Because

        my $seconds_per_day = 60 * 60 * 24; my $then = time - (14 * seconds_per_day);
        is, to me, at least as readable as ehdonhon's example of using Add_Delta_YMD and doesn't pollute the namespace either?

        Granted, the $seconds_per_day version takes a little extra work (remembering which indexes from (localtime($then)) you want and adding offsets to the extracted month and year if you intend to display them directly), but it's worthwhile to have more easily portable code, IMHO.

        For a larger project that's likely to need other modules, sure, Date::Calc is great. But if it's the only non-core module that would be used, I don't think it's worth the hassle of making people install it when you can do the same thing using only the core language with so little extra effort.

•Re: Subtracting Dates
by merlyn (Sage) on Jun 07, 2002 at 15:48 UTC
      Hmm. Maybe there's a misunderstanding?

      Have you visited realdates.use.pearls.com lately? ;) It's a different kind of 'glue language'.

(wil) Re: Subtracting Dates
by wil (Priest) on Jun 07, 2002 at 15:16 UTC
    Look into Date::Manip. I think you will need something like:
    use Date::Manip; my $err; my $date=&DateCalc("today","- 14 days",\$err); # OUTPUTS (at time of testing): # # 2002052408:15:05

    - wil
Re: Subtracting Dates
by ehdonhon (Curate) on Jun 07, 2002 at 15:25 UTC

    Date::Calc is your friend.

    use Date::Calc qw( Add_Delta_YMD ); my ( $curyear, $curmonth, $curday ) = ( 2002, 1, 1 ); my ( $deltayear, $deltamonth, $deltaday) = ( 0, 0, -14); my ( $year, $month, $day ) = Add_Delta_YMD( $curyear, $curmonth, $curday, $deltayear, $deltamonth, $deltaday );