Q:

How can I sort a dd/mm/yyyy formatted date by month using Perl?

I have a list of dd/mm/yyyy dates stored in a hash that I need to sequentially print out in order of date by month. Here is the relevant excerpt.
use feature 'say';

for my $date (sort {$a cmp $b} keys %data) {
    say $date;
}

This outputs:
16/07/2008
16/08/2008
16/09/2008
17/07/2008
17/08/2008
17/09/2008, etc.

when what I need is:
16/07/2008
17/07/2008
16/08/2008
17/08/2008
16/09/2008
16/09/2008, etc.

How can I achieve this?

A:

You can do it using a Schwartzian Transform, like so:
for my $date( map  { $_->[0] }
              sort { $a->[1] <=> $b->[1] } 
              map  { [ $_, (split /\//, $_)[1] ] }
              keys %data ) { 
    ...

This takes each key of %data and puts it in an anonymous array where the first element is the key and the second is the middle field from splitting on /. Then it sorts by the second element of the array, and uses another map to get the original list of keys.

A:

If the format is a rigid 10 chars:
sort { substr($a,3,2) cmp substr($b,3,2) } @dates;

A:

Parse and sort:
sub get_month {
    my $date = shift;
    my ($d, $m, $y) = split m{/}, $date;
    return $m;
}

sort { get_month($a) <=> get_month($b) } @dates;

I would probably use DateTime, though, since I want to work with objects, not meaningless strings:
my $parser = DateTime::Format::Natural->new(format => 'dd/mm/yyyy');
sort map { $parser->parse_datetime($_) } @dates;

