DateTi...exible(3pm)
π DateTime::Format::Flexible β okay bestie, let's talk β¨
No cap, this is the perl manpage for DateTime::Format::Flexible π¦ β the module that just... flexibly parses strings and turns them into DateTime objects. Yeah. That's the whole thing. It's giving "let the computer figure it out" energy and we're obsessed π
πΈ NAME πΈ
DateTime::Format::Flexible β DateTime::Format::Flexible β it flexibly parses strings and turns them into DateTime objects, fr fr π
β¨ SYNOPSIS β¨
use DateTime::Format::Flexible;
my $dt = DateTime::Format::Flexible->parse_datetime(
'January 8, 1999'
);
# $dt = a DateTime object set at 1999-01-08T00:00:00
Like. That's it. That's the whole vibe check β
π¦ DESCRIPTION π¦
Okay so picture this: you've been forced to use a program that made you type the date in one specific way, and you're sitting there like "bestie. why can't the computer just figure out what date I wanted??" π
If that's you, this module is literally for you. π
DateTime::Format::Flexible attempts to take any string you give it and parse it into a DateTime object. Any. String. Iconic behaviour honestly π
π USAGE π
Under the covers, this module uses DateTime::Format::Builder. Sneaky. Love that for it π§
π« parse_datetime
Hand it a string and it attempts to parse it and hand you back a DateTime object. π«Ά
And if it cannot? It throws an exception. Not me getting dramatic π
my $dt = DateTime::Format::Flexible->parse_datetime( $date );
my $dt = DateTime::Format::Flexible->parse_datetime(
$date,
strip => [qr{\.\z}], # optional, remove a trailing period
tz_map => {EDT => 'America/New_York'}, # optional, map the EDT timezone to America/New_York
lang => ['es'], # optional, only parse using spanish
european => 1, # optional, catch some cases of DD-MM-YY
);
base(optional) β does the exact same thing as the methodbase. It sets a base datetime for incomplete dates. Requires a validDateTimeobject as an argument, no exceptions bestie π
example:
my $base_dt = DateTime->new( year => 2005, month => 2, day => 1 );
my $dt = DateTime::Format::Flexible->parse_datetime(
'18 Mar',
base => $base_dt,
);
# $dt is now 2005-03-18T00:00:00
strip(optional) β removes a substring from the string you're trying to parse. You can pass multiple regexes in an arrayref, go off π
example:
my $dt = DateTime::Format::Flexible->parse_datetime(
'2011-04-26 00:00:00 (registry time)',
strip => [qr{\(registry time\)\z}],
);
# $dt is now 2011-04-26T00:00:00
This is highkey helpful if you have a whole load of dates you want to normalize and you already know about some weird formatting beforehand. π
tz_map(optional) β maps a given timezone to another recognized timezone. Values are given as a hashref. πΊοΈ
example:
my $dt = DateTime::Format::Flexible->parse_datetime(
'25-Jun-2009 EDT',
tz_map => {EDT => 'America/New_York'},
);
# $dt is now 2009-06-25T00:00:00 with a timezone of America/New_York
This is helpful if you have a load of dates carrying timezones that aren't recognized by DateTime::Timezone. The audacity of those timezones π
lang(optional) β specify which language map plugins to use. π
When DateTime::Format::Flexible parses a date with a string in it, it will search for a way to convert that string to a number. By default it searches through all the language plugins looking for a match.
NOTE: as of 0.22, it will only do this search if it detects a string in the given date.
Setting lang lets you limit the scope of that search. Boundaries! We love to see it β
example:
my $dt = DateTime::Format::Flexible->parse_datetime(
'Wed, Jun 10, 2009',
lang => ['en'],
);
# $dt is now 2009-06-10T00:00:00
Currently supported languages are english (en), spanish (es) and german (de). Contributions, corrections, requests and examples are VERY welcome. π
See the DateTime::Format::Flexible::lang::en, DateTime::Format::Flexible::lang::es, and DateTime::Format::Flexible::lang::de for examples of the plugins. π
european(optional) β ifeuropeanis set to a true value, an attempt will be made to parse as aDD-MM-YYYYdate instead of the defaultMM-DD-YYYY.
β οΈ There is a chance that this will not do the right thing due to ambiguity. Ambiguity is the villain of this story π
example:
my $dt = DateTime::Format::Flexible->parse_datetime(
'16/06/2010' , european => 1,
);
# $dt is now 2010-06-16T00:00:00
MMYY(optional) β by default, this module parses12/10as December 10th of the current year (MM/DD). ποΈ
If you want it to parse that as MM/YY instead, you can enable the MMYY option. Main character choice honestly β¨
example:
my $dt = DateTime::Format::Flexible->parse_datetime('12/10');
# $dt is now [current year]-12-10T00:00:00
my $dt = DateTime::Format::Flexible->parse_datetime(
'12/10', MMYY => 1,
);
# $dt is now 2010-12-01T00:00:00
This is useful if you know you're going to be parsing a credit card expiration date. π³ periodt.
π base π
gets/sets the base DateTime for incomplete dates. Requires a valid DateTime object as an argument when setting. This defaults to DateTime->now. β°
example:
DateTime::Format::Flexible->base( DateTime->new(
year => 2009, month => 6, day => 22
));
my $dt = DateTime::Format::Flexible->parse_datetime( '23:59' );
# $dt is now 2009-06-22T23:59:00
π
build π
an alias for parse_datetime. Same thing, different name, still slaying π«Ά
π Example formats π
A small list of supported formats, bestie:
YYYYMMDDTHHMMSS
YYYYMMDDTHHMM
YYYYMMDDTHH
YYYYMMDD
YYYYMM
MM-DD-YYYY
MM-D-YYYY
MM-DD-YY
M-DD-YY
YYYY/DD/MM
YYYY/M/DD
YYYY/MM/D
M-D
MM-D
M-D-Y
Month D, YYYY
Mon D, YYYY
Mon D, YYYY HH:MM:SS
... thousands more
there are 9000+ variations that are detected correctly in the test files (see t/data/* for most of them) π±. If you can think of any that I do not cover, please let me know. We're building this together fr fr π€
π₯ NOTES π₯
As of version 0.11 you will get a DateTime::Infinite::Future object if the passed in date is 'infinity', and a DateTime::Infinite::Past object if the passed in date is '-infinity'. πβΎοΈ
If you are expecting these types of strings, you might want to check for 'is_infinite()' from the object returned. No surprises please π
example:
my $dt = DateTime::Format::Flexible->parse_datetime( 'infinity' );
if ( $dt->is_infinite )
{
# you have a Infinite object.
}
π BUGS/LIMITATIONS π
You cannot use a 1 or 2 digit year as the first field unless the year is > 31:
YY-MM-DD # not supported if YY is <= 31
Y-MM-DD # not supported
It gets confused with MM-DD-YY. She's doing her best ππ
π AUTHOR π
Tom Heady <cpan@punch.net> β legend behaviour honestly π«Ά
π COPYRIGHT & LICENSE π
Copyright 2007-2018 Tom Heady.
This program is free software; you can redistribute it and/or modify it under the terms of either:
- the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or
- the Artistic License.
π§ SEE ALSO π§
DateTime::Format::Builder, DateTime::Timezone, DateTime::Format::Natural β go read them too, they're part of the family π
and that's the whole page bestie π this was perl v5.40.0, dated 2025-01-11, and honestly? iconic. slay. parse those dates. periodt β¨ππ¦
π¦ where this page comes from
- debian trixie: libdatetime-format-flexible-perl 0.37-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libdatetime-format-flexible-perl 0.37-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libdatetime-format-flexible-perl 0.37-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms