Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

How to subtract date by 1 day

by ewhitt (Scribe)
on Dec 13, 2007 at 09:54 UTC ( [id://656785]=perlquestion: print w/replies, xml ) Need Help??

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

I am using the following format for creating MySQL database names.
my $db_name = sprintf "%4d_%02d_%02d_%02d_%02d_%02d",$year+1900,$mon+1 +,$mday,$hour,$min,$sec;
Sample Output:

2007_12_13_04_49_15

Is there a way to take the date portion and subtract it by one day without using a module (if one exists)

Replies are listed 'Best First'.
Re: How to subtract date by 1 day
by Zaxo (Archbishop) on Dec 13, 2007 at 10:22 UTC

    Subtract 24*60*60 seconds from the unix time before using localtime to split into units.

    I recommend POSIX::strftime for converting that to a string.

    use POSIX 'strftime'; print strftime "%Y_%m_%d_%H_%M_%S/n", localtime() - 24 * 60 * 60;
    prints this time yesterday in your format.

    After Compline,
    Zaxo

      If by day, the OP means 24 hours, that's fine. If he just wants to move back the date one day without changing the time, your solution is wrong since not every day has 24*60*60 seconds. Use timegm+gmtime to do date manips.

      use POSIX qw( strftime ); use Time::Local qw( timegm ); my ($d,$m,$y) = (localtime())[3,4,5]; print(strftime("%Y_%m_%d\n", gmtime(timegm(0,0,0,$d,$m,$y) - 24*60*60) ));

      With time:

      use POSIX qw( strftime ); use Time::Local qw( timegm ); my ($sec,$min,$hour,$d,$m,$y) = localtime(); ($d,$m,$y) = (gmtime(timegm(0,0,0,$d,$m,$y) - 24*60*60))[3,4,5]; print(strftime("%Y_%m_%d_%H_%M_%S\n", $sec,$min,$hour,$d,$m,$y));
Re: How to subtract date by 1 day
by moritz (Cardinal) on Dec 13, 2007 at 10:06 UTC
    Sure there is a module:
    use Date::Simple qw(date); my $d = date("2007-12-12"); my $yesterday = $d - 1; print $yesterday;

    And of course it can be done without a module, because the module is written in Perl as well.

    If you want to see how it's done, look at the module's source.

Re: How to subtract date by 1 day
by andreas1234567 (Vicar) on Dec 13, 2007 at 10:14 UTC
    Using DateTime:
    $ perl -l use strict; use warnings; use DateTime; my $str = '2007_12_13_04_49_15'; $str =~ /^(\d+)_(\d+)_(\d+)_(\d+)_(\d+)/; my $dt = DateTime->new( year => $1, month => $2, day => $3, hour => $4, minute => $5 ); print $dt->ymd . ' ' . $dt->hms; $dt->add( days => -1 ); print $dt->ymd . ' ' . $dt->hms; __END__ 2007-12-13 04:49:00 2007-12-12 04:49:00
    --
    Andreas
      Thanks everyone for your input. 2008-01-01 seems to break things. Date::Simple returns 2007-00-01.
        Date::Simple (3.02) works for me (on Linux):
        use strict; use warnings; use Date::Simple qw(date); my $d = date("2008-01-01"); my $yesterday = $d - 1; print $yesterday; __END__ 2007-12-31
        Check the test reports and consider filing a bug report if the latest version doesn't work for you.
        --
        Andreas
Re: How to subtract date by 1 day
by tcf03 (Deacon) on Dec 13, 2007 at 10:47 UTC
    Using this example you should be able to format it any way you'd like. POSIX should be included in your distro, so you wont need to install a module.
    #!/usr/bin/perl use strict; use warnings; use POSIX qw(strftime); my $today = time; my $yesterday = $today - 60 * 24 * 60; my $formatted = strftime "%m/%d/%Y", ( localtime($yesterday) ); print "yesterday = $formatted\n";

    update
    What zaxo said...

    Ted
    --
    "That which we persist in doing becomes easier, not that the task itself has become easier, but that our ability to perform it has improved."
      --Ralph Waldo Emerson
Re: How to subtract date by 1 day
by cosmicperl (Chaplain) on Dec 13, 2007 at 15:53 UTC
    I tend to use a couple of routines I wrote. They take leap years into account, and expect the date to be passed in as YYYYMMDD

    sub DateNext { my ($y, $m, $d) = unpack('a4a2a2', $_[0]); my @daysinmonth = ("31","28","31","30","31","30","31","31","30","31" +,"30","31"); my @daysinmonthly = ("31","29","31","30","31","30","31","31","30","3 +1","30","31"); $d++; if (($y % 4) == 0) { if ($d > @daysinmonthly[$m - 1]) { $m++; if ($m > 12) { $m = 1; $y++; } ## End if $d = 1; } ## End if } ## End if else { if ($d > @daysinmonth[$m - 1]) { $m++; if ($m > 12) { $m = 1; $y++; } ## End if $d = 1; } ## End if } ## End else my $returndate = sprintf("%04d%02d%02d",$y,$m,$d); return $returndate; } ## End sub ### Brings date to the previous day sub DatePrevious { my ($y, $m, $d) = unpack('a4a2a2', $_[0]); my @daysinmonth = ("31","28","31","30","31","30","31","31","30","31" +,"30","31"); my @daysinmonthly = ("31","29","31","30","31","30","31","31","30","3 +1","30","31"); $d--; if (($y % 4) == 0) { if ($d < 1) { $m--; if ($m < 1) { $m = 12; $y--; } ## End if $d = @daysinmonthly[$m - 1]; } ## End if } ## End if else { if ($d < 1) { $m--; if ($m < 1) { $m = 12; $y--; } ## End if $d = @daysinmonth[$m - 1]; } ## End if } ## End else my $returndate = sprintf("%04d%02d%02d",$y,$m,$d); return $returndate; } ## End sub


    Lyle

      Actually, there is a flaw in your Leap_year logic. (This is why people who write date routines pull out their hair).

      A leap year is a year that is divisible by 4, but not by 100, unless it's divisible by 400. Not that your solution is likely to encouter the bug anytime soon. But the year 2100 is NOT a ly.

      --
      I used to drive a Heisenbergmobile, but every time I looked at the speedometer, I got lost.
      Leap year evaluation condition need to be updated-
      (((($y%4) == 0) && (($y%100) !=0)) || (($y%400) ==0) )
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://656785]
Approved by prasadbabu
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-20 02:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found