Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Date processor

by tune (Curate)
on Feb 23, 2001 at 22:27 UTC ( #60518=perlquestion: print w/replies, xml ) Need Help??

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

Hello All I have a text file, pipe-delimited, etc. Everyday task. One of the fields is a date I show an example of its format: 2-19-01 3:22 PM. The year is supposed to be in this millenium, so I don't have to worry about 19xx years.
I wrote the next code to process this string, and I would like to ask for the wisdom of doing it in one simple regexp (s/// or kind of).
if ($xpl[2]=~/^(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+:\d+)\s+([A|P]M)$/) { $xpl[2]=($3+2000)."-".$1."-".$2." ".(($6 eq "PM")?($4+12):$4). +":".$5; }
The result must be acceptable for Mysql's date column type.

Thank you in advance.

-- tune

Replies are listed 'Best First'.
Re: Date processor
by mr.nick (Chaplain) on Feb 23, 2001 at 22:41 UTC
    I'm not sure what format MySQL's date field is, but Time::ParseDate will parse your example string into a Unix format (# seconds since the epoch).
    use Time::ParseDate; my $time=parsedate("2-19-01 3:22 PM"); print scalar localtime($time),"\n";
      The easy way to use this more elegant approach of mr.nick would be to INSERT using the MySQL helper function:     INSERT INTO x (y) VALUES (FROM_UNIXTIME(?)); You might want to check out 7.4.11 of the MySQL docs for more detailed information.
      I'm with you. I think that using CPAN modules for converting dates, XML etc. is preferable to rolling one's own regexes. There is just too much opportunity for mischief with malformed dates, leap years, invalid input, etc.

      Personally I prefer Date::Manip for these sorts of tasks, but to each his own. Or a Serge Gainsbourg said, "A son gout est l'appetit, l'appetit est a son gout." (One's taste is according to one's appetite, one's appetite is according to one's taste.")

(ichimunki) re: Date processor
by ichimunki (Priest) on Feb 23, 2001 at 22:50 UTC
    This might not be a bad way to go if you are the only one who ever uses this script. But I'd think a series of splits combined with a clear "if" rather than the embedded ? will make the code a lot clearer and perhaps execute more quickly.
    my $time_stamp = "2-19-01 3:22 PM"; my($date, $time, $am_pm) = split(/ /, $time_stamp); my($month, $day, $short_year) = split(/-/, $date); my($hours, $min) = split(/:/, $time); if ($am_pm =~ /pm/i) { $hours += 12; } my $year = 2000 + short_year; my $sql_time_stamp = "$year-$month-$day $hours:$min"
    I know this looks a lot more like "baby talk Perl", but ask yourself which one you can read more easily without background info. Also ask yourself which one is easier to change if your date format (into or out of this function) ever changes.
Re: Date processor
by tadman (Prior) on Feb 23, 2001 at 22:45 UTC
    There doesn't appear to be anything fundamentally wrong with your strategy of using a regexp. There is no point in using the s/// substitution on your string, however, seeing as you are matching the entire string (/^...$/), and assignment using '=', such as you have done, is probably faster.

    If you were changing only part of the string from one format to another, you would likely be using s///, but since you are modifying the variables mathematically, you would have to use the s///e format, with the 'e' for eval switch turned on. That will evaluate the second part of the regexp, performing the math and replacing with the result.
Re: Date processor
by enoch (Chaplain) on Feb 23, 2001 at 22:52 UTC
    If you really wantto do this via code and not a prebuilt module, here it is (assuming date format is 'mmm dd yyyy hh:mm(am|pm)' that is 'Feb 19 2001 3:42pm').
    use strict; my $str = "2-19-01 3:49pm"; my %months = qw(1 Jan 2 Feb 3 Mar); my ($month,$day,$year,$time) = split /-|\s/,$str; my $dataDate = "$months{$month} $day 20$year $time\n"; print $dataDate;

Re: Date processor
by SilverB1rd (Scribe) on Feb 23, 2001 at 22:39 UTC
    I dont see how a s/// is going to help you any. For more information on regexp try going, here and here

    Price of Freedom is Eternal Vigilance
Re: Date processor
by tune (Curate) on Feb 24, 2001 at 00:19 UTC
    Okay, I was not really specific on the question. I know I can do it with split(), and with Date::Parser, but I was curious about a way with pure s///;. :-)

    BTW I have to worship the system admin for weeks while he start installing a new module... :(

    -- tune

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2022-09-25 02:56 GMT
Find Nodes?
    Voting Booth?
    I prefer my indexes to start at:

    Results (116 votes). Check out past polls.