http://www.perlmonks.org?node_id=112052

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

How to compare two dates dates.? Is there a way to compare dates directly without converting them to strings..!

Replies are listed 'Best First'.
Re: Date Comparison..?
by andreychek (Parson) on Sep 13, 2001 at 04:56 UTC
    As I pointed out on a previous topic, I've always found it easiest to deal with time/date stuff by first converting the dates I'm dealing with to seconds since the epoch (a numeric value). If you make use of the time function, it returns seconds since the epoch. If you have a date, and wish to convert it to seconds, you can use Time::Local to do so.

    Once you have your date in seconds, it's very easy to do tests and manipulations on that data. For an example, see the node I linked above. Good luck!

    -Eric
Re: Date Comparison..?
by rob_au (Abbot) on Sep 13, 2001 at 05:06 UTC
    I'm not exactly sure how you have got your dates stored, but if you have them as individual numbers rather than a combined string or in Gregorian day-format, then it may be worthwhile to have a look at Date::Calc. This module provides a many routines for date manipulation and comparison.

    And from the recipes section of the documentation ...

    1) How do I compare two dates? Solution #1: use Date::Calc qw( Date_to_Days ); if (Date_to_Days($year1,$month1,$day1) < Date_to_Days($year2,$month2,$day2)) if (Date_to_Days($year1,$month1,$day1) <= Date_to_Days($year2,$month2,$day2)) if (Date_to_Days($year1,$month1,$day1) > Date_to_Days($year2,$month2,$day2)) if (Date_to_Days($year1,$month1,$day1) >= Date_to_Days($year2,$month2,$day2)) if (Date_to_Days($year1,$month1,$day1) == Date_to_Days($year2,$month2,$day2)) if (Date_to_Days($year1,$month1,$day1) != Date_to_Days($year2,$month2,$day2)) $cmp = (Date_to_Days($year1,$month1,$day1) <=> Date_to_Days($year2,$month2,$day2)); Solution #2: use Date::Calc qw( Delta_Days ); if (Delta_Days($year1,$month1,$day1, $year2,$month2,$day2) > 0) if (Delta_Days($year1,$month1,$day1, $year2,$month2,$day2) >= 0) if (Delta_Days($year1,$month1,$day1, $year2,$month2,$day2) < 0) if (Delta_Days($year1,$month1,$day1, $year2,$month2,$day2) <= 0) if (Delta_Days($year1,$month1,$day1, $year2,$month2,$day2) == 0) if (Delta_Days($year1,$month1,$day1, $year2,$month2,$day2) != 0)

     

    This module is definitely worth spending some time investigating and experimenting with.

     

    Ooohhh, Rob no beer function well without!

Re: Date Comparison..?
by clintp (Curate) on Sep 13, 2001 at 04:14 UTC
    If they're not strings, then they must be numbers. If they're numbers then use ==. :)

    You probably need to give up a little more info than this for us to be helpful.

Re: Date Comparison..?
by tachyon (Chancellor) on Sep 13, 2001 at 08:22 UTC

    Here is a Time::Local example

    #!/usr/bin/perl -w use strict; use Time::Local; my %months = ( Jan => 0, Feb => 1, Mar => 2, Apr => 3, May => 4, Jun => 5, Jul => 6, Aug => 7, Sep => 8, Oct => 9, Nov => 10, Dec => 12); sub get_epoch_seconds { my $line = shift; # grab a scalar localtime looking like string from the line my ($wday,$mon,$mday,$hours,$min,$sec,$year) = $line =~ m/(\w\w\w)\s+(\w\w\w)\s+(\d{1,2})\s+(\d\d):(\d\d):(\d +\d)\s+(\d{4})/; die "Unable to find time like string in line:\n$line" unless $year +; $mon = $months{$mon}; # convert to numerical months 0 - 11 return timelocal($sec,$min,$hours,$mday,$mon,$year); } my $start = time(); my $string_start = scalar localtime ( $start ); print "Current time is $start epoch seconds\n"; print "As a string this is $string_start\n"; print "Converting string back into epoch seconds: ", get_epoch_seconds +($string_start), "\n"; sleep 1; my $string_finish = localtime; print "As a string it is now $string_finish\n"; my $finish = get_epoch_seconds($string_finish); print "This is $finish epoch seconds\n"; print "Comparing our times:\n"; print "$string_finish is after $string_start\n" if $finish > $start;

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print