Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Date module laziness

by Cody Pendant (Prior)
on Dec 05, 2004 at 02:03 UTC ( [id://412447]=perlquestion: print w/replies, xml ) Need Help??

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

I need two date functions for some code I'm working on. One, something that will take "31/12/04" or similar (European-style dd/mm/yy) and transform it into SQL-compatible "2004-12-31", and back again, and presumably chuck an error if it meets an illogical date (32/12/04 or whatever); two, I want it to calculate for me things like "the date three weeks after 31/12/04". Which module do I need?


($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss')
=~y~b-v~a-z~s; print

Replies are listed 'Best First'.
Re: Date module laziness
by dragonchild (Archbishop) on Dec 05, 2004 at 02:26 UTC
    Date::Calc will do it. Look towards the bottom of the function list for the american vs. european parsing functions for what you need to parse your date.

    Though, nearly every single database will allow you to specify how you want it to parse the date. For example, in Oracle, you would do TO_DATE( ?, 'DD/MM/YY' ) and in MySQL, you would do STR_TO_DATE( ?, '%d/%m/%y ). So, you don't have to parse it in Perl if you don't want to.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      Good point! Not only that, but in the spirit of laziness, I can also do the date addtion using MySQL as well with something like SELECT DATE_ADD(?, INTERVAL 21 DAY); so it looks like I don't need a date module at all...


      ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss')
      =~y~b-v~a-z~s; print
Re: Date module laziness
by data64 (Chaplain) on Dec 05, 2004 at 02:45 UTC

      I'll have to go with data64 on this one. DateTime is quite easy to use and usually gets the job done.

      More info can also be found at http://datetime.perl.org/

      --
      b10m

      All code is usually tested, but rarely trusted.
Re: Date module laziness
by bobf (Monsignor) on Dec 05, 2004 at 06:12 UTC

    As already mentioned, the Date::Calc module will do the trick. Specifically, look at the Decode_Date_US and Decode_Date_EU functions for parsing out the day, month, and year. Unless I'm mistaken, though, you'll have to employ something like sprintf to format the date. There is also the check_date function to verify the date is valid.

    In the spirit of TMTOWTDI, though, you could also use the Date::Manip module. It has different strengths than Date::Calc, and it might be useful for other projects. Here is how you could do this using Date::Manip:

    use strict; use warnings; use Date::Manip; my $rawdate = '10/12/04'; Date_Init( "DateFormat = US" ); # default munge_date( $rawdate ); Date_Init( "DateFormat = European" ); munge_date( $rawdate ); $rawdate = '32/12/04'; munge_date( $rawdate ); sub munge_date { my ( $rawdate ) = @_; my %cfgvars = map { split( '=', $_ ) } Date_Init(); print "DateFormat is set to $cfgvars{DateFormat}, ", "parsing $rawdate:\n"; my $date = DateCalc( $rawdate, "+ 1 week" ); if( not defined $date ) { print " $rawdate is not a valid date\n"; return; } print ' orig date = ', UnixDate( $rawdate, "%b %e, %Y" ), "\n"; print ' + 1 week = ', UnixDate( $date, "%m/%d/%y" ), " (mm/dd/yy)\n"; print ' ', UnixDate( $date, "%d/%m/%y" ), " (dd/mm/yy)\n"; print ' ', UnixDate( $date, "%Y-%m-%d" ), " (yyyy-mm-dd)\n"; } ** OUTPUT ** DateFormat is set to US, parsing 10/12/04: orig date = Oct 12, 2004 + 1 week = 10/19/04 (mm/dd/yy) 19/10/04 (dd/mm/yy) 2004-10-19 (yyyy-mm-dd) DateFormat is set to European, parsing 10/12/04: orig date = Dec 10, 2004 + 1 week = 12/17/04 (mm/dd/yy) 17/12/04 (dd/mm/yy) 2004-12-17 (yyyy-mm-dd) DateFormat is set to European, parsing 32/12/04: 32/12/04 is not a valid date
    If you use Date::Manip, make sure to set a default value for the timezone variable. If the timezone cannot be determined automatically, you'll get an error.

Re: Date module laziness
by bradcathey (Prior) on Dec 05, 2004 at 13:51 UTC

    First of all, Cody Pendant, it has nothing to do with laziness. That's why we're all PMs.

    I'm a big fan of Date::Calc, but it is missing some formatting functions, so you will need to rely on sprintf if you need output in a particular format, especially if you need full dates. Date::Calc will return 2004-4-5, so you might need sprintf to 'round' things out to 2004-04-05.


    —Brad
    "Don't ever take a fence down until you know the reason it was put up." G. K. Chesterton
Re: Date module laziness
by infidel2112 (Acolyte) on Dec 05, 2004 at 16:06 UTC
    Try Date::Calc

    http://search.cpan.org/~stbey/Date-Calc-5.4/Calc.pod

    Kevin

Re: Date module laziness
by Paulster2 (Priest) on Dec 05, 2004 at 20:27 UTC

    My favorite has always been Date::Manip as it is quite useful. It also has an extensive doc that makes it more than that. bobf above seems to have a lock on it. Check into this mod as it is well worth the time.

    Paulster2


    You're so sly, but so am I. - Quote from the movie Manhunter.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2024-04-19 01:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found