Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Adding Days To YYYYMMDD Date Format

by Zoomie (Novice)
on May 17, 2012 at 00:05 UTC ( #970956=perlquestion: print w/ replies, xml ) Need Help??
Zoomie has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

I hope you can help me wrie a subroutine to add a number of days to a date in the yyyymmdd format.

I want to add x days to it.

Example:

20120516 + 24 = 20120609

Thanks for your help...

Comment on Adding Days To YYYYMMDD Date Format
Re: Adding Days To YYYYMMDD Date Format
by sauoq (Abbot) on May 17, 2012 at 00:25 UTC

    The right way to do this is to parse it into a number of seconds as would be returned by time() and then to add the number of seconds in a day times the number of days you want, and then convert it back.

    use Date::Parse; my $day = 24*60*60; my $x = 3; # set this. my $xdays = $x * $day; print scalar localtime(str2time("20121231") + $xdays);

    Update: Changed to produce the requested format and to use the given example. Apparently I have too much time on my hands.

    use Date::Parse; my $date = "20120516"; my $day = 24*60*60; my $x = 24; # set this. my $xdays = $x * $day; # see perldoc -f localtime. my @t = (localtime(str2time($date) + $xdays))[5,4,3]; $t[0] += 1900; # localtime returns years since 1900. $t[1] += 1; # localtime returns month in range 0..11. printf "%04d%02d%02d\n", @t;

    -sauoq
    "My two cents aren't worth a dime.";

      When doing a lot of these calculations with dates, keeping the dates in a standard localtime list can prove very useful. When iso-dates are to be generated like in this example, calculation is faster than printf:

      use Benchmark qw(cmpthese); my @d = localtime; cmpthese (-1, { prnt => sub { my $x = sprintf "%d%02d%02d", 1900 + $d[5], $d[4] + 1, $d[3]; }, calc => sub { my $x = (($d[5] + 1900) * 100 + $d[4] + 1) * 100 + $d[3]; }, }); => Rate prnt calc prnt 2025658/s -- -37% calc 3215550/s 59% --

      And yes, I did have a long running process where millions of these were done, so it did matter.


      Enjoy, Have FUN! H.Merijn

      Hi Sauoq,

      I installed the Date module. (I use Active State Perl).

      When I test your script, I got the message:

      Can't locate Date/Parse.pm.

      Any idea what I should do?

      Thanks...

        Can't locate Date/Parse.pm.

        Any idea what I should do?

        Buy a chicken. Wait for full moon. At midnight, draw a pentragram with its blood. Place yourself and your computer inside the pentagram. Then, open a terminal and type cpan Date::Parse.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        Try the Date::Calc solution below as it works using the Active State distribution.

      Hi sauoq.

      I added the module Date::Parse from CPAN and your script runs perfectly.

      Thanks so much for your help...

Re: Adding Days To YYYYMMDD Date Format
by Kenosis (Priest) on May 17, 2012 at 02:43 UTC

    Here's another option:

    use Modern::Perl; use Date::Calc qw(Add_Delta_Days); say addDaysToDate( 20120516, 24 ); sub addDaysToDate { sprintf '%d%02d%02d', Add_Delta_Days( $_[0] =~ /(\d{4})(\d{2})(\d{2})/, $_[1] ); }

    Output:

    20120609

    Hope this helps!

      I got error with the Modern::Perl.

      Thanks...

      Hi Kenosis

      I added the module Modern::Perl, ran your script, but the result is not correct.

      I changed your sprintf '%d%02d%02d' to sprintf '%04d%02d%02d'.

      Using the same sample, it prints out 00001200.

      <Thanks...

      Kenosis.

      It works now!

      Thanks very much!

Re: Adding Days To YYYYMMDD Date Format
by live4tech (Sexton) on May 17, 2012 at 04:19 UTC
    The DateTime module from CPAN is also useful.
Re: Adding Days To YYYYMMDD Date Format
by tobyink (Abbot) on May 17, 2012 at 22:36 UTC
    use DateTimeX::Auto qw(:auto); my $date = '2012-05-16'; $date->add(days => 24); print "$date\n";
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      This is elegant and very readable, tobyink! Nice work...

        I meant to add... I've uploaded a new version of DateTimeX::Auto so now it's possible to just do:

        use DateTimeX::Auto qw(:auto); my $future = '2012-05-19' + 'P3Y4M2D'; # says '2015-09-21' say $future;

        The duration format isn't the most readable, but it's an ISO standard (ISO 8601 duration), so fairly well documented if you Google for it.

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2014-10-22 02:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (112 votes), past polls