Perl日期格式转换

3
我从一个HTML表单中获取了02/29/2012,但之后需要使用ISO格式的2012-02-29进行操作。 我确定如果不涉及我完全不理解的JS日期选择器,使用Perl会更容易。请注意保留HTML标记。
8个回答

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

由于输入不可信(Web表单...),因此应更严格地检查输入格式。特别注意,\d匹配任何Unicode数字,而不仅仅是ASCII数字。因此,choroba的答案更安全。 - dolmen

5
要进行转换,只需使用:

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

据我所知,ISO标准日期格式不是YYYY-DD-MM,而是YYYY-MM-DD。


1
ISO 8601(相关标准)确实使用YYYY-MM-DD表示日期(除非您正在处理周,此时使用YYYY-Www-d,或者您正在处理年和年内天数的序数日期YYYY-DDD等)。 - Jonathan Leffler
您的输入格式非常严格,拒绝单个数字作为日期或月份,以及除了4位数字之外的任何年份。这不一定是一个重大的问题,但接受多样化的输入格式并坚持生成严格的输出格式通常是一个好的系统,特别是如果人们正在生成输入数据。 - Jonathan Leffler

2
你可以使用DateTimeDate::Manip。有很多子程序可以执行各种日期操作。例如,使用Date::Manip:
$string = '02/29/2012';
$date = ParseDate($string);
$out = UnixDate($date, '%Y-%m-%d');

编辑:我看到在我打字的时候已经提供了一个类似的答案。

1

使用标准的Perl:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

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

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

使用 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;

如果你想在Perl中处理日期和时间,那么DateTime及其相关工具就是你需要的工具。

1

您可以使用Date::Manip::Date模块。

这个方法会比较耗费资源,但是可以验证日期的有效性。


0
由于输入不可信(来自网络表单等),我建议基本上使用choroba的答案(添加了边界检查),但在测试中检查输入是否匹配:
# 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

0

这取决于你要在日期上做多少工作,以及你是否会在文化上意识到不同的人如何输入日期,以及是否愿意接受月份名称或缩写以及纯数字等方式。

CPAN上,有一个关于数据和数据类型的主要部分,其中包括日期时间的子部分,每个部分都有许多模块。有些非常复杂:例如,DateTime模块非常全面,但比较笨重(并且未列在日期或时间部分中)。其他一些则很巧妙:Date::CalcDate::Manip。在CPAN的主要问题是太多选择了 - 你需要的东西可能已经存在其中。
如果其他答案中的简单正则表达式可以工作,请使用它们。否则,考虑使用Date::Calc或Date::Manip之一,除非您找到了其他更适合您的解决方案。

好的,我注意到正则表达式可以工作(而且它只适用于一组非常有限的用户)。考虑到即将推出的HTML5输入功能,我更愿意保持脚本易于适应,并准备好摆脱JS选择器。 - Recct

0

strptime 函数还可以从核心模块 Time::Piece 中利用:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接