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

I am having trouble setting up my date variable.
%day2t = qw( Friday T Saturday T-1 Sunday T-2 Monday T-3 Tuesday T-4 Wednesday T-5 Thursday T-6 ); $tday = $day2t {"$day"};
So I already have some code to determine what day it is and once I know the current day, I set my $tDay variable depending on that.
My next step is to to take this $tDay variable and and subtract that amount from the current date. So, if $tDay contains "t-4", I need to subtract that from today's date.

For example, Today is Monday. So $tDay variable will be set to "T-3". Today's date is 25-Nov-2013. I need to be able to subtract 3 from 25 to get 22 as my final answer. I know how to do this but the part where I am having trouble is how to set 30 or 31 or 28 days for specific months. If current date is 4 and I have to subtract 5 from it, how do I handle that? Please help.

Replies are listed 'Best First'.
Re: Setting up date to subtract specific number from it
by Corion (Patriarch) on Nov 25, 2013 at 15:32 UTC

    See DateTime, or maybe localtime and Time::Local.

    Personally, I wrote my own tiny date addition/subtraction library, which consecutively adds 22 hours worth of seconds to timestamps until the date string changes.

Re: Setting up date to subtract specific number from it
by daxim (Curate) on Nov 25, 2013 at 16:11 UTC
    use 5.014; use DateTime qw(); my %day2t = ( Friday => 'T', Saturday => 'T-1', Sunday => 'T-2', Monday => 'T-3', Tuesday => 'T-4', Wednesday => 'T-5', Thursday => 'T-6', ); { my $today = DateTime->now->truncate(to => 'day'); # 2013-11-25T00: +00:00 $today->day_name; # Monday $day2t{$today->day_name}; # T-3 my $into_the_past = ($day2t{$today->day_name} =~ s/T-?//r) || 0; # + 3 $today->clone->subtract(days => $into_the_past)->strftime('%F'); # + 2013-11-22 } { my $beginning_of_november = DateTime->new(year => 2013, month => 1 +1, day => 1); # 2013-11-01T00:00:00 $beginning_of_november->day_name; # Friday $day2t{$beginning_of_november->day_name}; # T my $into_the_past = ($day2t{$beginning_of_november->day_name} =~ s +/T-?//r) || 0; # 0 $beginning_of_november->clone->subtract(days => $into_the_past)->s +trftime('%F'); # 2013-11-01 }
      I really appreciate your help! Just wondering if there is a way to do this without using the Date::Time module? I am not a root user on my box and I am supposed to be avoiding the use of modules as much as possible. Thanks!

        "...as much as possible."

        Good, so they left you a little room to work with. I mean "as much as possible" isn't as restrictive as "none at all, ever, for any reason."

        Date manipulation is one of the situations where modules are invaluable. Hand rolled solutions usually miss something. Do they want date bugs, or date modules?

        Perhaps you could ask your client what date modules they already have installed, and work using one of those.


        Dave

Re: Setting up date to subtract specific number from it
by locked_user sundialsvc4 (Abbot) on Nov 25, 2013 at 16:07 UTC

    Well, if you just search for “date” at http://search.cpan.org, you will today get 5000 hits ...

    Some suggestions of packages that I have used very often:

    • DateTime will do absolutely anything with a date.   Takes a bit of time to grok its examples, but once you do, it’s worth it.
    • Date::Manip is another object-oriented interface for dates.   Again, there is a learning curve.
    • Date::Simple ... well, it’s simple.   Put down your Swiss Army® knife and grab this pocket-knife which happens to have the blades you use most often.

    But there are literally thousands more, including some pure-fun ones.   Search as-above for “DateTime Calendar” and then get your time-machine ready:   DateTime::Calendar::Mayan, DateTime::Calendar::FrenchRevolutionary, DateTime::Fiction::JRRTolkien::Shire ...

    The one thing you don’t have to do in Perl is to “write your own” routines to handle positively anything that has to do with dates/times.   I find it very convenient to use the packages which define a date-time object, i.e. “this thing ‘is a’ date/time, its internal implementation is blissfully opaque, and I can tell it to do things and ask it questions and It Just Works.™”   Functional interfaces are much more baroque due to the sheer number of options that must be supported by a thorough handling of dates.

Re: Setting up date to subtract specific number from it
by kcott (Archbishop) on Nov 26, 2013 at 06:33 UTC

    G'day vihar,

    You can do this very easily with the builtin modules Time::Piece and Time::Seconds.

    Here's an example using Sunday, 1-Dec-2013 which, using your figures, should have 2 days subtracted; resulting in Friday, 29-Nov-2013.

    #!/usr/bin/env perl -l use strict; use warnings; use Time::Piece; use Time::Seconds; my %day2t = qw{Fri 0 Sat 1 Sun 2 Mon 3 Tue 4 Wed 5 Thu 6}; my $test_date = '1-Dec-2013'; my $t_now = Time::Piece->strptime($test_date, '%d-%b-%Y'); my $t_mod = $t_now - ONE_DAY * $day2t{$t_now->day}; print 'Time now: ', $t_now->strftime; print 'Time modified: ', $t_mod->strftime;

    Output:

    Time now: Sun, 01 Dec 2013 00:00:00 UTC Time modified: Fri, 29 Nov 2013 00:00:00 UTC

    Notes:

    • I've used abbreviations for the day names. If you need the full names, use the fullday() method instead of the day() method.
    • I've reduced your T and T-n values to simple digits. If you need the forms you originally posted, you'll have to add some additional code.

    -- Ken