http://www.perlmonks.org?node_id=23065

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question: (dates and times)

I need to parse dates that are in the standard format:

    Mon Jul 17 17:59:31 2000

Currently i'm using Date::Parse but this is fairly slow.
Does anyone have a specialized and possibly faster way to do it?
Maybe a combination of split() with table lookup?

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: Fast(er) date parsing
by spoon! (Initiate) on Nov 07, 2005 at 05:07 UTC
    I think the POSIX::strptime module is what you're looking for. It has an strptime() function that acts as the inverse of strftime():
    use POSIX::strptime; use Time::Local; my $result = timelocal strptime $d, '%a %b %e %H:%M:%S %Y';
Re: Fast(er) date parsing
by lhoward (Vicar) on Jul 19, 2000 at 01:29 UTC
    Since you know the format and the format is constant then the fastest parser would probably be a split, followed by a month name to month number lookup table. Then take all your numbers and add throw them into an apropriate equation to get the timestamp format and voila.
Re: Fast(er) date parsing
by fundflow (Chaplain) on Jul 20, 2000 at 02:08 UTC
    Thanks guys, maybe i wasn't clear. I want to get the unix timing (since epoch) from the data and was wondering if there is an inverse function to strftime(). I just realized that its not that hard and so here is my solution, following lhoward's suggestion:
    use Time::Local; my %months = ( Jan=> 0, Feb=> 1, Mar=> 2, Apr=> 3, May=>4, Jun=> 5, Jul=> 6, Aug=> 7, Sep=> 8, Sep=> 8, Oct=> 9, Nov=> 10, Dec= +> 11); # Parse the date: Fri Jun 30 11:07:39 2000 my ($day, $month, $mday, $time, $year)=split(" ", $d); my ($hour,$min,$sec)=split(":",$time); my $result = timelocal($sec,$min,$hour,$mday,$months{$month},$year);

    I'd prefer not having to use any module but this seems reasonable
    The reason i need this is to go through some log files and print a summary of the events that happened in the past 24 hours.

      If you just want to check if the event was in the last 24 hours without using any module, you could compare
      my @yesterday=localtime time-24*60*60; if( (sprintf"%02d"x6, $yesterday[5]+1900,@yesterday[4,3,2,1,0]) < (sprintf"%02d"x6, $year,$months{$month},$mday,$hour,$min,$sec) )
Re: Fast(er) date parsing
by crazyinsomniac (Prior) on Jul 19, 2000 at 03:01 UTC
    my( $day, $month, $date, $time, $hour, $min, $sec, $year); ($day,$month,$date,$time,$year)=split(" ","Mon Jul 17 17:59:31 2000"); ($hour,$min,$sec)=split(":",$time);
      Sorry about that
      my $day; my $month; my $date; my $time; my $hour; my $min; my $sec; my $year; ($day,$month,$date,$time,$year)=split(" ","Mon Jul 17 17:59:31 2000") +; ($hour,$min,$sec)=split(":",$time);
       ______________________________________________
      |_____¸.·ooO--(> cRaZy is co01. <)--Ooo·.¸_____|
       ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
      
        my ($day,$month,$date,$hour,$min,$sec,$year)=split /[ :]/,"Mon Jul 17 +17:59:31 2000";
        cLive ;-)
Re: Fast(er) date parsing
by chanio (Priest) on Nov 08, 2005 at 14:53 UTC
    See the great Date::Calc that has plenty of functions to do this:
    perl -MDate::Calc -e'my $string="8 nov,2005";my ($year,$month,$day)= D +ate::Calc::Decode_Date_EU($string); print("\n$year/$month/$day\n")' 2005/11/8