I have this date time format in string "11:56:41, 11/22/2011".
Here's what I want:
Compare two date time strings like.
$date1 = "11:56:41, 11/22/2011";
$date2 = "11:20:41, 11/20/2011";
if($date2 < $date1) {
do something...
} else {
do nothing...
}
Any ideas how could i achieve this in perl?
One more solution that uses the overloaded comparisons after converting the times to Time::Piece
objects. Creating the objects may be overkill for something simple, but they can become very useful if you need to do other things with the times.
use Time::Piece;
my $dateformat = "%H:%M:%S, %m/%d/%Y";
my $date1 = "11:56:41, 11/22/2011";
my $date2 = "11:20:41, 11/20/2011";
$date1 = Time::Piece->strptime($date1, $dateformat);
$date2 = Time::Piece->strptime($date2, $dateformat);
if ($date2 < $date1) {
do something...
} else {
do nothing...
}
An efficient method is to reorder the fields to something lexically comparable.
sub to_comparable {
my ($date) = @_;
my ($H,$M,$S,$d,$m,$Y) = $date =~ m{^([0-9]{2}):([0-9]{2}):([0-9]{2}), ([0-9]{2})/([0-9]{2})/([0-9]{4})\z}
or die;
return "$Y$m$d$H$M$S";
}
if (to_comparable($date2) lt to_comparable($date1)) {
...
} else {
...
}
What, already 4 hours and not a single DateTime (all hail the mighty DateTime) answer in sight? You're slacking, perl subscribers… ☻
use DateTime::Format::Strptime qw();
my $p = DateTime::Format::Strptime->new(pattern => '%T, %D', on_error => 'croak',);
my $date1 = $p->parse_datetime('11:56:41, 11/22/2011');
my $date2 = $p->parse_datetime('11:20:41, 11/20/2011');
if($date2 < $date1) {
say "$date2 comes before $date1";
} else {
say "$date2 does not come before $date1";
}
The method parse_datetime
returns instances of DateTime
whose comparison operators and stringification are overloaded to DTRT.
Convert the datetimes (in your case these are local datetimes because they have no time zones) into ISO8601 then you can do regular string comparison.
To perform the conversion, you should extract the six components from your format
HH:MM:SS, mm/DD/YYYY
and reassemble them into ISO 8601:
YYYY-MM-DDTHH:MM:SS
Then a normal lexicographic comparison will work.
See http://codepad.org/berle9um
Repeated here:
sub my_format_to_iso8601 {
$_[0] =~ /(\d\d):(\d\d):(\d\d), (\d\d)\/(\d\d)\/(\d\d\d\d)/;
return "$6-$4-$5T$1:$2:$3";
}
$date1 = "11:56:41, 11/22/2011";
$date2 = "11:20:41, 11/20/2011";
$d1 = my_format_to_iso8601($date1);
$d2 = my_format_to_iso8601($date2);
print "first is $d1\n";
print "second is $d2\n";
if ($d2 < $d1) {
print "second is earlier\n";
} else {
print "first is earlier\n";
}
ADDENDUM
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With