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

Greetings fellow Monks
I am using Date::Manip. What I want to do is generate 90 days from the current date and enter it into a MySql table, which also has the datatype as DATE.
The date when i insert into the field, comes as the year 2020, instead of 2004. the month and day field are okay.
The code for inserting is as shown below. Please help me out.
#!/usr/bin/perl # get current Date from MySql use warnings; use strict; use DBI; use Date::Manip; my ($dbh, $rows); $dbh=DBI->connect('dbi:mysql:VISA','root','elephant') || die "Error opening database: $DBI::errstr\n"; my $date; #$date = DateCalc("today","+ 90 days"); $date=ParseDate("in 90 days"); print "Date: $date\n"; $rows=$dbh->do("INSERT INTO appCancel (appt_date,status, no_cancel, ci +ty) VALUES('$date' , 'U' , '0' , 'M')") || die "Couldn't insert record : $DBI::errstr"; $dbh->finish();
the date which comes into the record has 2020 as the year.

Replies are listed 'Best First'.
Re: Date::Manip Help
by davido (Cardinal) on May 10, 2004 at 05:07 UTC
    I've done some testing, and some reading in the docs. Now I'll post my speculation.

    Date::Manip's DateParse() function, in scalar context, returns a string that looks like yyyymmddhh:mm:ss.

    Reading in the docs for MySQL here: http://dev.mysql.com/doc/mysql/en/DATETIME.html... I don't see where the format returned by Date::Manip's DateParse() function is a format recognized by MySQL. You probably need to at least massage the format by removing the colons from the string. At that point MySQL's date field should recognize the format and act appropriately.

    Reading further in the documentation for Date::Manip I found this nugget of information:

    INTERNAL


    When a date is parsed using ParseDate, that date is stored in an internal format which is understood by the Date::Manip routines UnixDate and DateCalc. Originally, the format used to store the date internally was:
    YYYYMMDDHH:MN:SS
    It has been suggested that I remove the colons (:) to shorten this to:
    YYYYMMDDHHMNSS
    The main advantage of this is that some databases are colon delimited which makes storing a date from Date::Manip tedious.

    In order to maintain backwards compatibility, the Internal variable was introduced. Set it to 0 (to use the old format) or 1 (to use the new format).

    You can set the internal representation of Date::Manip's date string by using the Date_Init() function. Setting Date_Init('INTERNAL=1'); before you call DateParse() will force the return value of DateParse() to look like, "YYYYMMDDHHMMSS" (note, no colons).

    That's just one possibility. Not sure if I'm on target, because I haven't tested the theory, but give it a try and see if it solves your problem.


    Dave

Re: Date::Manip Help
by Jaap (Curate) on May 10, 2004 at 06:41 UTC
    You could also use the new(er) DateTime module(s) which have functions for exporting in the MySQL format and much more.
Re: Date::Manip Help
by Zaxo (Archbishop) on May 10, 2004 at 07:35 UTC

    MySQL has builtin functions to add time intervals. See, from the command line, info mysql Reference Functions 'Date and time functions'. The DATE_ADD() function is what you want, together with CURDATE()

    After Compline,
    Zaxo

Re: Date::Manip Help
by sacked (Hermit) on May 10, 2004 at 15:12 UTC
    You need to change the format of your date to that used by MySQL (YYYY-MM-DD) before calling your INSERT statement. You can do this with Date::Manip::UnixDate:
    $date= ParseDate("in 90 days"); $date= UnixDate( $date => '%Y-%m-%d' ); print "Date: $date\n"; # 2004-08-08 $rows=$dbh->do("INSERT INTO appCancel (appt_date,status, no_cancel, ci +ty) VALUES('$date' , 'U' , '0' , 'M')") || die "Couldn't insert record : $DBI::errstr";
    See the section on UnixDate in the pod for Date::Manip.

    --sacked
      I tried the following, but all the dates in the table are coming the same
      $date=ParseDate("today"); my @city=("C","K","D"); my ($j,$fut); $fut=ParseDate("in 90 days"); for ($j=0;$j<3;$j++) { my $i; for ($i=1;$i<90;$i++) { # $date=ParseDate("in 1 day"); $date= UnixDate( $date => '%Y-%m-%d' ); print "Date: $date\n"; # $rows=$dbh->do("INSERT INTO appCancel (appt_date,status, no_c +ancel, city) # VALUES ('$date','U','0', '$city[ +$j]')") || # die "Couldn't insert record : $DBI::errstr"; $date=ParseDate("in 1 day"); print "Date: $date\n"; } }
      the number of records being generated is 267? and not 270
        Please take a look at the documentation for Date::Manip, as I suggested in my earlier post. You need the DateCalc function to calculate ($somedate + 1 day).

        Regarding your code above, in your original post, it wasn't clear that you wanted to enter every date from tomorrow to 90 days from now. If that's the case, you need to create a new date object for each day:
        #!/usr/bin/perl # get current Date from MySql use warnings; use strict; use Date::Manip; + my @city=("C","K","D"); my $j; for ($j=0;$j<3;$j++) { my $date= ParseDate("today"); + my $i; + # either start from 0, or use <= for ($i=1;$i<=90;$i++) { $date= DateCalc($date, "+ 1 day"); $date= UnixDate($date, '%Y-%m-%d'); print "Date: $date, city: $city[$j]\n"; } }
        The reason you were only getting 267 records is because your inner loop only executed 89 times:
        for ($i=1;$i<90;$i++)
        You either need to initialize $i to 0 or change the conditional expression to $i <= 90.

        If you'd like to speed up the code, you should reverse the loop structure, with the date calculation in the outer loop (so each date is only calculated once rather than three times). Also note that the code below uses Perl-style loops rather than C-style:
        #!/usr/bin/perl # get current Date from MySql use warnings; use strict; use Date::Manip; + my @city=("C","K","D"); + my $date= ParseDate("today"); + # using a Perl-style (not C-style) loop helps prevent # the error seen in the earlier loop construct for my $i ( 1 .. 90 ) { $date= DateCalc($date, "+ 1 day"); $date= UnixDate($date, '%Y-%m-%d'); + for my $j ( 0 .. 2 ) { print "Date: $date, city: $city[$j]\n"; } }
        Hope this helps,

        --sacked