Perl — Разные парсеры дат для DateTime модуля

Разные парсеры дат для DateTime модуля.

DateTime::Format::Builder creates DateTime parsers. Many string formats of dates and times are simple and just require a basic regular expression to extract the relevant information. Builder provides a simple way to do this without writing reams of structural code. DateTime::Format::Builder creates DateTime parsers. Many string formats of dates and times are simple and just require a basic regular expression to extract the relevant information. Builder provides a simple way to do this without writing reams of structural code. Фреймворк для написания своего парсера. Если сходу формат даты непонятно чей, может быть проще написать свой парсер (хотя лучше опознать формат). На основе написаны модификации DateTime::Format::Builder::Parser::Strptime и  DateTime::Format::Builder::Parser::Regex

package DateTime::Format::Brief;
use DateTime::Format::Builder (
parsers => {
parse_datetime => [
{
regex => qr/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/,
params => [qw( year month day hour minute second )],
},
{
regex => qr/^(\d{4})(\d\d)(\d\d)$/,
params => [qw( year month day )],
},
],
}
);
DateTime::Format::Builder::Parser::Strptime strptime takes as its argument a strptime string. See DateTime::Format::Strptime for more information on valid patterns.
my $parser = DateTime::Format::Builder->create_parser(
strptime => '%e/%b/%Y:%H:%M:%S %z',
);
DateTime::Format::ICal This module understands the ICal date/time and duration formats, as defined in RFC 2445. It can be used to parse these formats in order to create the appropriate objects.

use DateTime::Format::ICal;
my $dt = DateTime::Format::ICal->parse_datetime( '20030117T032900Z' );
my $dur = DateTime::Format::ICal->parse_duration( '+P3WT4H55S' );
# 20030117T032900Z
DateTime::Format::ICal->format_datetime($dt);
# +P3WT4H55S
DateTime::Format::ICal->format_duration($dur);

DateTime::Format::RFC3501 Parse and format RFC3501 datetime strings. (RFC 3501 -IMAP, INTERNET MESSAGE ACCESS PROTOCOL)

use DateTime::Format::RFC3501;
my $f = DateTime::Format::RFC3501->new();
my $dt = $f->parse_datetime( ' 1-Jul-2002 13:50:05 +0200' );
# 1-Jul-2002 13:50:05 +0200
print $f->format_datetime($dt);

DateTime::Format::RFC3339 Parse and format RFC3339 datetime strings (Date and Time on the Internet: Timestamps)

use DateTime::Format::RFC3339;
my $f = DateTime::Format::RFC3339->new();
my $dt = $f->parse_datetime( '2002-07-01T13:50:05Z' );
# 2002-07-01T13:50:05Z
print $f->format_datetime($dt);

DateTime::Format::ISO8601 Parses ISO8601 formats

use DateTime::Format::ISO8601;
my $dt = DateTime::Format::ISO8601->parse_datetime( $str );
my $dt = DateTime::Format::ISO8601->parse_time( $str );
or
my $iso8601 = DateTime::Format::ISO8601->new;
my $dt = $iso8601->parse_datetime( $str );
my $dt = $iso8601->parse_time( $str );

Форматы:

Формат Пример Описание
YYYY-MM 2005-08 август 2005 года
YYYYMMDD 20050809 9 августа 2005 года
YYYY-MM-DD 2005-08-09 9 августа 2005 года
hhmm 1831 18 часов 31 минута
hh:mm 18:31 18 часов 31 минута
hhmmss 183142 18 часов 31 минута 42 секунды
hh:mm:ss 18:31:42 18 часов 31 минута 42 секунды
±hh +03 UTC+03 часа
-03 UTC-03 часа
±hhmm +0330 UTC+03 часа 30 минут
-0330 UTC-03 часа 30 минут
±hh:mm +03:30 UTC+03 часа 30 минут
-03:30 UTC-03 часа 30 минут
hhmmss±hh 183142+03 18 часов 31 минута 42 секунды UTC+03 часа
183142-03 18 часов 31 минута 42 секунды UTC-03 часа
hh:mm:ss±hh 18:31:42+03 18 часов 31 минута 42 секунды UTC+03 часа
18:31:42-03 18 часов 31 минута 42 секунды UTC-03 часа
hhmmss±hhmm 183142+0330 18 часов 31 минута 42 секунды UTC+03 часа 30 минут
183142-0330 18 часов 31 минута 42 секунды UTC-03 часа 30 минут
hh:mm:ss±hh:mm 18:31:42+03:30 18 часов 31 минута 42 секунды UTC+03 часа 30 минут
18:31:42-03:30 18 часов 31 минута 42 секунды UTC-03 часа 30 минут
YYYYMMDDThhmmss 20050809T183142 9 августа 2005 года 18 часов 31 минута 42 секунды
YYYY-MM-DDThh:mm:ss 2005-08-09T18:31:42 9 августа 2005 года 18 часов 31 минута 42 секунды
YYYYMMDDThhmmss±hh 20050809T183142+03 9 августа 2005 года 18 часов 31 минута 42 секунды UTC+03 часа
20050809T183142-03 9 августа 2005 года 18 часов 31 минута 42 секунды UTC-03 часа
YYYY-MM-DDThh:mm:ss±hh 2005-08-09T18:31:42+03 9 августа 2005 года 18 часов 31 минута 42 секунды UTC+03 часа
2005-08-09T18:31:42-03 9 августа 2005 года 18 часов 31 минута 42 секунды UTC-03 часа
YYYYMMDDThhmmss±hhmm 20050809T183142+0330 9 августа 2005 года 18 часов 31 минута 42 секунды UTC+03 часа 30 минут
20050809T183142-0330 9 августа 2005 года 18 часов 31 минута 42 секунды UTC-03 часа 30 минут
YYYY-MM-DDThh:mm:ss±hh:mm 2005-08-09T18:31:42+03:30 9 августа 2005 года 18 часов 31 минута 42 секунды UTC+03 часа 30 минут
2005-08-09T18:31:42-03:30 9 августа 2005 года 18 часов 31 минута 42 секунды UTC-03 часа 30 минут
YYYY-MM-DDThh:mm:ss[.mmm] 2005-08-09T18:31:42 9 августа 2005 года 18 часов 31 минута 42 секунды
2005-08-09T18:31:42.201 9 августа 2005 года 18 часов 31 минута 42 секунды 201 миллисекунда

DateTime::Format::Atom Parse and format Atom datetime strings (ISO 8601 , RFC 4287, The Atom Syndication Format). Внутри парсера используется DateTime::Format::RFC3339.

use DateTime::Format::Atom;
my $f = DateTime::Format::Atom->new();
my $dt = $f->parse_datetime( '2002-07-01T13:50:05Z' );
# 2002-07-01T13:50:05Z
print $f->format_datetime($dt);

DateTime::Format::Salesforce Parses datetime formats returned by the Salesforce REST API. These claim to by ISO 8601 but subtly deviate from the standard, and hence can’t be parsed by DateTime::Format::ISO8601. This code is based heavily on that module and supports only the formats received from Salesforce. Есть какие-то тонкие отличия от ISO 8601.

1999-11-02T23:12:00.456+0400DateTime::Format::W3CDTF Parse and format W3CDTF datetime strings. Возможно, ISO 8601 его полностью включает.

use DateTime::Format::W3CDTF;
my $w3c = DateTime::Format::W3CDTF->new;
my $dt = $w3c->parse_datetime( '2003-02-15T13:50:05-05:00' );
# 2003-02-15T13:50:05-05:00
$w3c->format_datetime($dt);

DateTime::Format::DateParse Parses Date::Parse compatible formats:

1995:01:24T09:08:17.1823213           ISO-8601
 1995-01-24T09:08:17.1823213
 Wed, 16 Jun 94 07:29:35 CST           Comma and day name are optional 
 Thu, 13 Oct 94 10:13:13 -0700
 Wed, 9 Nov 1994 09:50:32 -0500 (EST)  Text in ()'s will be ignored.
 21 dec 17:05                          Will be parsed in the current time zone
 21-dec 17:05
 21/dec 17:05
 21/dec/93 17:05
 1999 10:02:18 "GMT"
 16 Nov 94 22:28:20 PST

DateTime::Format::HTTP This module provides functions that deal the date formats used by the HTTP protocol (and then some more). Ниже список форматов из HTTP::Date:

"Wed, 09 Feb 1994 22:23:32 GMT"       -- HTTP format
 "Thu Feb  3 17:03:55 GMT 1994"        -- ctime(3) format
 "Thu Feb  3 00:00:00 1994",           -- ANSI C asctime() format
 "Tuesday, 08-Feb-94 14:15:29 GMT"     -- old rfc850 HTTP format
 "Tuesday, 08-Feb-1994 14:15:29 GMT"   -- broken rfc850 HTTP format

 "03/Feb/1994:17:03:55 -0700"   -- common logfile format
 "09 Feb 1994 22:23:32 GMT"     -- HTTP format (no weekday)
 "08-Feb-94 14:15:29 GMT"       -- rfc850 format (no weekday)
 "08-Feb-1994 14:15:29 GMT"     -- broken rfc850 format (no weekday)

 "1994-02-03 14:15:29 -0100"    -- ISO 8601 format
 "1994-02-03 14:15:29"          -- zone is optional
 "1994-02-03"                   -- only date
 "1994-02-03T14:15:29"          -- Use T as separator
 "19940203T141529Z"             -- ISO 8601 compact format
 "19940203"                     -- only date

 "08-Feb-94"         -- old rfc850 HTTP format    (no weekday, no time)
 "08-Feb-1994"       -- broken rfc850 HTTP format (no weekday, no time)
 "09 Feb 1994"       -- proposed new HTTP format  (no weekday, no time)
 "03/Feb/1994"       -- common logfile format     (no time, no offset)

 "Feb  3  1994"      -- Unix 'ls -l' format
 "Feb  3 17:03"      -- Unix 'ls -l' format

 "11-15-96  03:52PM" -- Windows 'dir' format

DateTime::Format::Mail Convert between DateTime and RFC2822/822 formats. Включает некоторые форматы с более или менее серьёзными ошибками.

use DateTime::Format::Mail;
# From RFC2822 via class method:
my $datetime = DateTime::Format::Mail->parse_datetime(
    "Sat, 29 Mar 2003 22:11:18 -0800"
);
print $datetime->ymd('.'); # "2003.03.29"

#  or via an object

my $pf = DateTime::Format::Mail->new();
print $pf->parse_datetime( "Fri, 23 Nov 2001 21:57:24 -0600" )->ymd; # "2001-11-23"

# Back to RFC2822 date

use DateTime;
my $dt = DateTime->new(
    year => 1979, month => 7, day => 16,
    hour => 16, minute => 45, second => 20,
    time_zone => "Australia/Sydney"
);
my $str = DateTime::Format::Mail->format_datetime( $dt );
print $str; # "Mon, 16 Jul 1979 16:45:20 +1000"

# or via an object
$str = $pf->format_datetime( $dt );
print $str; # "Mon, 16 Jul 1979 16:45:20 +1000"

Leave a Reply