使用DateTime-> compare()对日期进行排序

时间:2019-04-29 18:05:50

标签: perl

我正在尝试使用DateTime按时间顺序对日期数组进行排序:

use strict;
use warnings;
use Data::Printer;
use Date::Time;
use DateTime::Format::Strptime;

my $strp = DateTime::Format::Strptime->new(
    pattern   => '%D',
    time_zone => 'America/New_York',
);
 my @dates = (
    [1, '5/18/2011'],
    [2, '6/18/2011'],
    [3, '6/18/2014'],
    [4, '6/18/2010'],
);

my @res = sort { date_sort( $a->[1], $b->[1], $strp ) } @dates;

p \@res;

sub date_sort {
    my ( $date1, $date2, $strp ) = @_;

    my $dt1 = $strp->parse_datetime($date1);
    my $dt2 = $strp->parse_datetime($date2);
    return DateTime->compare($dt1, $dt2);
}

输出

[
    [0] [
        [0] 1,
        [1] "5/18/2011"
    ],
    [1] [
        [0] 2,
        [1] "6/18/2011"
    ],
    [2] [
        [0] 3,
        [1] "6/18/2014"
    ],
    [3] [
        [0] 4,
        [1] "6/18/2010"
    ]
]

预期输出

[
    [0] [
        [0] 4,
        [1] "6/18/2010"
    ],
    [1] [
        [0] 1,
        [1] "5/18/2011"
    ],
    [2] [
        [0] 2,
        [1] "6/18/2011"
    ],
    [3] [
        [0] 3,
        [1] "6/18/2014"
    ]
]

2 个答案:

答案 0 :(得分:3)

%D等效于%m/%d/%y,其中%y是两位数的年份。您要使用格式%m/%d/%Y支持四位数的年份。使用%D(和%m/%d/%y),您所有的输入都被解释为具有2020年。

答案 1 :(得分:3)

[这是评论而不是答案]

在这里使用DateTime是过分的。

sub date_sort {
    my ( $date1, $date2 ) = @_;
    $date1 = sprintf '%3$s%1$02s%2$02s', split /\//, $date1;
    $date2 = sprintf '%3$s%1$02s%2$02s', split /\//, $date2;
    return $date1 cmp $date2;
}

my @res = sort { date_sort( $a->[1], $b->[1] ) } @dates;

更好

use Sort::Key qw( ikeysort );

sub date_key {
    my ( $date ) = @_;
    return sprintf '%3$s%1$02s%2$02s', split /\//, $date;
}

my @res = ikeysort { date_key( $_->[1] ) } @dates;