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

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

I'd like to be able to check if a given date is between 2 other specific dates (these 2 will always be within the 60 days mof the date when the script is run). I have seen postings that indicate using the Date::Calc module - actually the Date-Calc module which I read somewhere is the compiled binary version of the module so I installed it via PPM. However in browsing this module, I found that it contains C components so requires the C compiler which I do not have on my Windows 2000 system. Or perhaps there is some easier way to determine if the given date falls between the 2 other specified dates? Btw, I am new to Perl. I also went to http://www.apache.org/dyn/closer.cgi/perl/win32-bin/ but got "The page cannot be found" for each link I tried there. I'd appreciate any help that can be offered.Thanks. Stacy
  • Comment on Checking if a given date falls between 2 other specific dates

Replies are listed 'Best First'.
Re: Checking if a given date falls between 2 other specific dates
by chargrill (Parson) on Apr 20, 2006 at 04:59 UTC

    Date::Manip is one module that's pure perl, and by the author's documentation, attempts to be the swiss army knife of date modules.

    But if that doesn't help, a search on CPAN might. Last time I needed something to do with dates (earlier today, in fact), I did a search, read through some of the various module's documentation, and picked the one that made the most sense.



    --chargrill
    $,=42;for(34,0,-3,9,-11,11,-17,7,-5){$*.=pack'c'=>$,+=$_}for(reverse s +plit//=>$* ){$%++?$ %%2?push@C,$_,$":push@c,$_,$":(push@C,$_,$")&&push@c,$"}$C[$# +C]=$/;($#C >$#c)?($ c=\@C)&&($ C=\@c):($ c=\@c)&&($C=\@C);$%=$|;for(@$c){print$_^ +$$C[$%++]}
Re: Checking if a given date falls between 2 other specific dates
by johngg (Canon) on Apr 20, 2006 at 08:53 UTC
    If your date strings are consistent and simple to break down then you would be able to use the Time::Local module which is a standard part of Perl. The localtime() function turns date values for second, minute etc. into the number of seconds elapsed since the epoch for your particular o/s. Like this

    my $epochSecs = localtime($secs, $mins, $hours, $mday, $mon, $year);

    Note that $mon is 0 for January to 11 for December.

    Once you have converted your three dates to epoch seconds you can do a simple numeric comparison.

    If, however, your date strings are complex and inconsistent then using a module as chargrill suggests would probably be less painful.

    Cheers,

    JohnGG

    Update: tag cock-up corrected

Re: Checking if a given date falls between 2 other specific dates
by blazar (Canon) on Apr 20, 2006 at 09:33 UTC

    To put it briefly: if you install a binary module (i.e. containing C code to be compiled) with PPM, then you'll get a binary version (i.e. complete of compiled binaries suitable for your architecture & current perl). In any case, you should not "browse this module" - unless you're curious about its implementation, that is. You installed it, then you can read its documentation with perldoc and use it straight out of the box: did you try doing so?

Re: Checking if a given date falls between 2 other specific dates
by monsterzero (Monk) on Apr 20, 2006 at 23:43 UTC
    You did not specify what format your dates are in. But no matter, DateTime can handle most date/time functions.
    use strict; use warnings; use DateTime; use DateTime::Span; use Datetime::Format::ISO8601; my $iso8601 = DateTime::Format::ISO8601->new; while (<DATA>) { my ( $first, $last ) = split('\|'); chomp $last; my $dt_set = DateTime::Span->from_datetimes( start => $iso8601->parse_datetime($first), before => $iso8601->parse_datetime($last), ); if ( $dt_set->contains( DateTime->now() ) ) { print "Within date range\n"; } else { print "Not within date range\n"; } } __DATA__ 1998-02-14|1998-03-01 2006-04-10|2006-06-01
    I hope this helps.
Re: Checking if a given date falls between 2 other specific dates
by TedPride (Priest) on Apr 20, 2006 at 17:36 UTC
    Convert the dates to a numerical, fixed-width, greatest significance first format. For instance, if you have Feb 12, 06, you could translate that to 060112, then compare numerically:
    use strict; use warnings; my $date1 = dateconvert('Jan 11, 04'); my $date2 = dateconvert('Jan 30, 04'); my $date3 = dateconvert('Feb 10, 04'); print "$date1 <= $date2 <= $date3 ? "; print $date1 <= $date2 && $date2 <= $date3 ? "Yes" : "No"; BEGIN { my @mon = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/; my %mon; $mon{$mon[$_]} = $_ for 0..$#mon; sub dateconvert { my $date = $_[0]; my ($mon, $day, $year) = $date =~ m/(\w+) (\d+), (\d+)/; $mon = $mon{$mon}; return sprintf("%02d%02d%02d", $year, $mon, $day); } }
    This is easily modified for different formats by changing a couple lines in the function.