Recct
Recct

Reputation: 923

Perl date format transformations

I'm taking 02/29/2012 from an html form, but will need to work with the ISO 2012-02-29 from then on. I am certain that it'd be easier for me to do it with Perl without touching on the JS datepicker of which I have zero understanding.

Upvotes: 3

Views: 4921

Answers (8)

dolmen
dolmen

Reputation: 8714

As the input is not trusted (web form...) I suggest to basically use choroba's answer (with bounds checking added), but in a test that checks if the input matches:

# input and result are in $_
unless (s{^([0-9]{2})/([0-9]{2})/([0-9]{4})$}{$3-$2-$1}) {
    die "invalid input";
}
# From here input is both validated and transformed

Upvotes: 0

JRFerguson
JRFerguson

Reputation: 7526

The strptime function can also be leveraged from the core module, Time::Piece :

use Time::Piece;
my $date = q(02/29/2012);
my $t    = Time::Piece->strptime( $date, "%m/%d/%Y" );
print $t->ymd, "\n";

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 755074

It depends on how much work you're going to be doing on the dates, and whether you're going to be culturally aware of how different people enter dates, and whether you're going to accept month names or abbreviations as well as pure numerics, and ...

On CPAN, there's a major section on Data and Data Types which has sub-sections for Date and Time with many modules in each. Some are extremely elaborate: for example, the DateTime module is extremely thorough, but rather heavy-weight (and is listed in neither the Date nor the Time section). Others are just clever: Date::Calc and Date::Manip. The main problem at CPAN is the embarrassment of riches - what you need is probably there.

If the simple regexes in other answers will work, use them. Otherwise, consider one of Date::Calc or Date::Manip, unless you find something else that will work better for you.

Upvotes: 0

Dave Cross
Dave Cross

Reputation: 69314

Using standard Perl:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my $date = '02/09/2012';

say join '-', (split m|/|, $date)[2,1,0];

Using DateTime:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use DateTime::Format::Strptime;

my $date = '02/09/2012';

my $parser = DateTime::Format::Strptime->new(
               pattern => '%d/%m/%Y',
             );

my $dt = $parser->parse_datetime($date);
say $dt->ymd;

If you want to deal with dates and times in Perl, then DateTime and its friends are the tools that you want.

Upvotes: 1

ArtMat
ArtMat

Reputation: 2150

You could use DateTime or Date::Manip. There are a plenty of subroutines that perform various manipulations with date. For example, using Date::Manip:

$string = '02/29/2012';
$date = ParseDate($string);
$out = UnixDate($date, '%Y-%m-%d');

Edit: as I see, a similar answer was provided while I was typing

Upvotes: 2

Sean Bright
Sean Bright

Reputation: 120714

$date = '02/29/2012';
$date =~ s#(\d+)/(\d+)/(\d+)#$3-$1-$2#;

Upvotes: 5

Bharat B
Bharat B

Reputation: 143

You can use the Date::Manip::Date module.

This is a little costlier but does validation of the dates.

Upvotes: 1

choroba
choroba

Reputation: 242383

To do your transformation, just use

s{([0-9]{2})/([0-9]{2})/([0-9]{4})}{$3-$2-$1}

But AFAIK, ISO is not YYYY-DD-MM, but YYYY-MM-DD.

Upvotes: 5

Related Questions