Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Coverting Date Formats

by tomazos (Deacon)
on Mar 05, 2002 at 16:14 UTC ( [id://149414]=perlquestion: print w/replies, xml ) Need Help??

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

I want to insert some dates into a MySQL table.

The data is from two sources.


One of them (an apache log), has the date format...

  "[27/Feb/2002:05:05:51 -0800]"

...which I assume I have to convert to 20020227050551 to get into MySQL.


The other one (a sybase dump), has the date format:

  "2002-02-23 01:27:25 -0800"

Which I assume I have to convert to 20020223012725 to get into MySQL.


I suppose I could just write a complex regexp to convert, but is there any builtin/modules I could use to make the job easier?

Any ideas appreciated.

Replies are listed 'Best First'.
Re: Coverting Date Formats
by gmax (Abbot) on Mar 05, 2002 at 16:25 UTC
    I would recommend Date::Manip.
    It has plenty of methods to read dates from the most demanding formats and you can convert them at will.
    _ _ _ _ (_|| | |(_|>< _|

      It might however be worth bearing in mind that in the Date::Manip documentation there is a section:

      SHOULD I USE DATE::MANIP If you look in CPAN, you'll find that there are a number of Date and Time packages. Is Date::Manip the one you should be using? In my opinion, the answer is no about 90% of the time. This sounds odd coming from the author of the software, but read on.
      You will probably want to read the rest of that section before making a decision to use that module :)

      /J\

        The decision to use that module or not depends mostly on performance, as pointed out by davorg in his book. We pay a high price when we have a high number of dates to scan and convert.
        My personal choice is to use a regex if I only have a small script with just one spot dealing with simple dates.
        However, when dealing with databases, I use Date::Manip, even if I have only one occurrence in the script. The reason is that in this way, I have a consistent management of dates in all my database scripts.


        We should compare efficiency vs. ease of coding. I mostly use Perl for database maintenance and data migration (with DBI, of course!) Especially for the latter, Date::Manip is wonderful. I can get dates from the most exotic formats and throw them at the database. We might say that, having a million records to migrate, it can take five minutes more than using a simple regex. True, but if our simple regex was too simple and not smart enough to deal with different date formats, then we might end up coding for hours trying to get it right, while Date::Manip will relieve us of such burden.

        Every situation is different. We should make some accurate measurement if we want to include Date::Manip for web usage. But for administration, AFAIAC, it's a godsend.
        _ _ _ _ (_|| | |(_|>< _|
        MySQL can handle the second format just fine. The first format will give you some problems. You're going to have to do some kind of manipulation to it before you do an insert.

        I'd have to concur with gellyfish on this one -- Date::Manip is probably overkill in this instance. I think rolling your own is the best solution in this case. You should be able to convert it to the desired format with a simple regex and a hash to handle the month abbreviations:

        #!/usr/bin/perl -w use strict; $_ = "[27/Feb/2002:05:05:51 -0800]"; my %months = ( Jan => '01', Feb => '02', # ... Dec => '12', ); m|\[(\d*)/(\D*)/(\d*):(\d*:\d*:\d*) [^\]]*\]|; print "$3-$months{$2}-$1 $4";
        That regex can probably be polished up a bit, but it should suit your purposes. If you do want to go ahead with Date::Manip, something like this should work:
        #!/usr/bin/perl -w use strict; use Date::Manip; $_ = "[27/Feb/2002:05:05:51 -0800]"; s/\[|\]//g; # Strip the brackets for Date::Manip $_ = ParseDate($_); s/://g; # Strip the colons for MySQL print;
        If you decide to use either implementation, please test them thoroughly before use.

        -- grummerX

Re: Coverting Date Formats
by Kanji (Parson) on Mar 05, 2002 at 19:30 UTC

    You might want to take a look at Time::Piece (alt.), which does just this sort of thing ...

    use Time::Piece; my %format = ( Apache => "[%d/%b/%Y:%T -0800]", MySQL => "%Y%m%d%H%M%S", Sybase => "%Y-%m-%d %T -0800", ); my @dates = ( [ "[27/Feb/2002:05:05:51 -0800]" => "Apache" ], [ "2002-02-23 01:27:25 -0800" => "Sybase" ], ); foreach my $date ( @dates ) { my($str,$type) = @$date; my $t = Time::Piece->strptime( $str, $format{$type} ); print $t->strftime( $format{"MySQL"} ), $/; }

        --k.


Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-19 00:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found