Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 13 of 13
  1. #1
    Regular Coder
    Join Date
    May 2007
    Posts
    162
    Thanks
    13
    Thanked 0 Times in 0 Posts

    Check if date between two dates, ignore year

    Hi,

    I need to determine if a date (month and day) is between two other month/days.

    I've attached an image to this post that describes what I'm trying to do. Basically the example "current day" is highlighted in red, and it's between those nearest dates (mar 15 and nov 22). However, when I use unix timestamps and artificially add a year to the dates, the script thinks that Nov 22 hasn't occurred yet, and therefore it suggests that Feb 1 is before Mar 15 AND Nov 22, instead of in between them.

    Hopefully this makes sense. I'd just like to compare dates using months and days, but ignoring year, and using a framework like the wheel I show on the image.

    Thanks for any help!!!

    S

  • #2
    Senior Coder whizard's Avatar
    Join Date
    Jan 2005
    Location
    Philadelphia, PA, USA
    Posts
    1,662
    Thanks
    14
    Thanked 76 Times in 76 Posts
    Maybe this? It's ugly, but...

    PHP Code:
    function compareDates($timestampDate1,$timestampDate2,$timestampDate3)
    {
     
    $beginMonth date("n"$timestampDate1);
     
    $beginDay date("j"$timestampDate1);
     
    $middleMonth date("n"$timestampDate2);
     
    $middleDay date("j"$timestampDate2);
     
    $endMonth date("n"$timestampDate3);
     
    $endDay date("j"$timestampDate3);
     
     
     if(
    $beginMonth != $endMonth)
     {
      if(
    $middleMonth $beginMonth)
      {
       if(
    $middleMonth $endMonth)
       {
        return 
    true;
       }
       else
       {
        if(
    $middleDay $endDay)
        {
         return 
    true;
        }
        else
        {
         return 
    false;
        }
       }  
      }
      else
      {
       if(
    $middleDay $beginDay)
       {
        return 
    true;
       }
       else
       {
        return 
    false;
       }
      }
     }
     else
     {
      if(
    $beginDay $middleDay && $endDay $middleDay)
      {
       return 
    true;
      }
      else
      {
       return 
    false;
      }
     }

    PHP Tip: If you want to use short tags (<? or <?=$var) then make sure short_open_tag is set to "1". It really helps.

    Don't forget to save everyone time and mark your thread as Resolved :)

    "Also note that it is your responsibility to die() if necessary."

    DON'T USE THE MYSQL_ EXTENSION

  • Users who have thanked whizard for this post:

    shadkeene (07-09-2013)

  • #3
    Senior Coder whizard's Avatar
    Join Date
    Jan 2005
    Location
    Philadelphia, PA, USA
    Posts
    1,662
    Thanks
    14
    Thanked 76 Times in 76 Posts
    Alternatively if you gave it a leap year date in the past, say, 2008, would it work then, since the year is complete?

    HTH
    Dan
    PHP Tip: If you want to use short tags (<? or <?=$var) then make sure short_open_tag is set to "1". It really helps.

    Don't forget to save everyone time and mark your thread as Resolved :)

    "Also note that it is your responsibility to die() if necessary."

    DON'T USE THE MYSQL_ EXTENSION

  • #4
    Regular Coder
    Join Date
    May 2007
    Posts
    162
    Thanks
    13
    Thanked 0 Times in 0 Posts
    Thanks whizard for these posts. I don't think the first covers the times when a month like Feb is in between Apr and Oct, where Oct is the 10th month, but really Feb occurs after it, even though it thinks it's less than Oct (2<10). Am I missing something?

    if($middleMonth > $beginMonth)

    It's almost as if I'd need to take the currrent day, dynamically force it to be the middle of the year in Julian days (i.e. Feb 1 = 182 instead of 32) and force the other dates into the same Julian scheme, so Apr 1 would be 241 and Oct 1 would be ((241+183) - 365)= 59.

    This seems WAY too complicated though, considering what I'm trying to do seems fairly simple.

    In any case I've uploaded a new image, with years, in my test case example, trying to describe the problem better.

  • #5
    Senior Coder
    Join Date
    Jan 2011
    Location
    Missouri
    Posts
    4,313
    Thanks
    23
    Thanked 612 Times in 611 Posts
    <?php

    $target = 0201; // feb 01
    $date1 = 0315; // mar 15
    $date2 = 1122; // nov22

    if(($date1 < $target) && ($date2 < $target))
    {
    echo "Is not between";
    }else{
    echo "Between";
    }
    ?>
    Evolution - The non-random survival of random variants.

    "If you leave hydrogen alone, for long enough, it begins to think about itself."

  • #6
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    This one's not correct. If target is 0101, and date one is 1122 and date2 is 0315, that will be issued as a not between, when it is. Also, don't forget that:
    0101 = 65
    1122 = 1122
    0315 = 205
    Which could alter your numbers logic by a lot.
    The idea is correct, but the application is wrong since it doesn't account for years rolling past even when we don't accommodate the year.
    I can think of a few ways that'd deal with this, but dateTime is probably the easiest:
    PHP Code:
    function isDateBetween(DateTime $dtTargetDateTime $dtStartDateTime $dtEnd)
    {
        
    $bResult false;
        if (
    $dtStart $dtEnd)
        {
            
    // We'll be checking "outside" of the range instead of inside.
            
    $bResult = !($dtTarget $dtEnd && $dtTarget $dtStart);
        }
        else
        {
            
    $bResult $dtTarget >= $dtStart && $dtTarget <= $dtEnd;
        }
        return 
    $bResult;

    I haven't tested this, but that *seems* to work okay in my head. You'd use it simply as:
    PHP Code:
    $dtStart = new DateTime('November 11');
    $dtEnd = new DateTime('March 3');
    $dtTarget = new DateTime('February 12');
    printf('%s is between %s and %s?  %d' PHP_EOL,
        
    $dtTarget->format('F j'),
        
    $dtStart->format('F j'),
        
    $dtEnd->format('F j'),
        
    isDateBetween($dtTarget$dtStart$dtEnd)); 
    For example. Note there are no years here, but the implicit year is this year. If you add years, it will override the implicit which can constrain the window or open it wider. So if you were to base this on a time provided with a year, you'd need to strip the year out (or use mktime and then wrap that in a dateTime).
    You'd need to test that out quite a bit, especially with some wider and narrower windows. Best I can figure in my head here is that on a year by year basis this won't be a problem; the endtime should be good even if you provide years since a year override would still fit in to the comparisons.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • Users who have thanked Fou-Lu for this post:

    shadkeene (07-11-2013)

  • #7
    Senior Coder
    Join Date
    Jan 2011
    Location
    Missouri
    Posts
    4,313
    Thanks
    23
    Thanked 612 Times in 611 Posts
    This one's not correct.
    Right, modified.
    <?php

    $target = 0201; // feb 01
    $date1 = 0315; // mar 15
    $date2 = 1122; // nov22

    if((($date1 < $target) && ($date2 < $target)) || (($date1 > $target) && ($date2 > $target)))
    {
    echo "Is not between";
    }else{
    echo "Between";
    }
    ?>

    Don't know what this means
    0101 = 65
    1122 = 1122
    0315 = 205
    Which could alter your numbers logic by a lot.
    Evolution - The non-random survival of random variants.

    "If you leave hydrogen alone, for long enough, it begins to think about itself."

  • Users who have thanked sunfighter for this post:

    shadkeene (07-11-2013)

  • #8
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    I mean that you're numbers will end up out of wack if you do that. For example:
    PHP Code:
    $jul31 0731;
    $sept30 0930;
    if (
    $sept30 $jul31)
    {
        print 
    'This is always true since $sept30 is equal to 0 (0930 is not a valid number)';

    The comparisons still are not correct though. You want this (again, I'd need to test to be 100% sure on this :P):
    Code:
     if(($date1 < $target && $date2 > $target) || !($date1 > $target && $date2 < $target))
    Otherwise it would end up like (2 scenarios):
    Code:
    $target = 201; // feb 01
    $date1 = 315; // mar 15
    $date2 = 1122; // nov22
    if(315 < 201 && 1122 < 201 || 315 > 201 && 1122 > 201) 
    =
    if (false && false || true && true)
    =
    if (false || true)
    =
    if (true)
    // this condition is aok, but. . .
    
    $target = 801; // aug 01
    $date1 = 315; // mar 15
    $date2 = 1122; // nov22
    
    if(315 < 801 && 1122 < 801 || 315 > 801 && 1122 > 801) 
    =
    if (true && false || false && true)
    =
    if (false || false)
    =
    if (false)
    I'd still suggest either a full timestamp (anchored to current year and altered), or datetime would be the easiest route overall.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #9
    Senior Coder
    Join Date
    Jan 2011
    Location
    Missouri
    Posts
    4,313
    Thanks
    23
    Thanked 612 Times in 611 Posts
    This is an impossible task without using the years, because the target date can always be shown to be between two dates in a circular system.
    Feb 1 is between Jan 1 and Jan 2, cause it's Jan 1 of this year and Jan 2 of next year.
    Evolution - The non-random survival of random variants.

    "If you leave hydrogen alone, for long enough, it begins to think about itself."

  • #10
    New Coder
    Join Date
    Dec 2011
    Posts
    87
    Thanks
    5
    Thanked 14 Times in 14 Posts
    Quote Originally Posted by sunfighter View Post
    This is an impossible task without using the years, because the target date can always be shown to be between two dates in a circular system.
    Feb 1 is between Jan 1 and Jan 2, cause it's Jan 1 of this year and Jan 2 of next year.
    I would imagine one would be making the assumption that the person would be only using one calendar year in the first place.
    True courage is about knowing not when to take a life, but when to spare one. PDO Tutorial

  • #11
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    This is why I suggest the use of date handling instead of number handling; its very easy to infer my years and modify as necessary (I don't actually have to check two sets of ranges, I can adjust years in cases instead if I wanted to). IMO its much better to check the ranges instead of adjusting the numbers.
    Without the year, it's impossible to determine whether its one day or one year. The only thing that can be done in this scenario is if the start is > the end, you may infer a 364.25 day window.
    So its not *impossible* to deal without the year, but it is limited to a < 365.25 day window.
    DateTime or straight timestamps are still the way to go.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #12
    Senior Coder
    Join Date
    Jan 2011
    Location
    Missouri
    Posts
    4,313
    Thanks
    23
    Thanked 612 Times in 611 Posts
    I agree 100% if he limits this to 365 day window. And looking at his diagram that looks the case.
    Evolution - The non-random survival of random variants.

    "If you leave hydrogen alone, for long enough, it begins to think about itself."

  • #13
    Regular Coder
    Join Date
    May 2007
    Posts
    162
    Thanks
    13
    Thanked 0 Times in 0 Posts
    Thanks so much!! This works with what I've tested so far. This helps determine which "window" one is in, even with the 4 ranges being dynamic.

    Thanks for your time and simple but powerful code.

    Quote Originally Posted by Fou-Lu View Post
    This one's not correct. If target is 0101, and date one is 1122 and date2 is 0315, that will be issued as a not between, when it is. Also, don't forget that:
    0101 = 65
    1122 = 1122
    0315 = 205
    Which could alter your numbers logic by a lot.
    The idea is correct, but the application is wrong since it doesn't account for years rolling past even when we don't accommodate the year.
    I can think of a few ways that'd deal with this, but dateTime is probably the easiest:
    PHP Code:
    function isDateBetween(DateTime $dtTargetDateTime $dtStartDateTime $dtEnd)
    {
        
    $bResult false;
        if (
    $dtStart $dtEnd)
        {
            
    // We'll be checking "outside" of the range instead of inside.
            
    $bResult = !($dtTarget $dtEnd && $dtTarget $dtStart);
        }
        else
        {
            
    $bResult $dtTarget >= $dtStart && $dtTarget <= $dtEnd;
        }
        return 
    $bResult;

    I haven't tested this, but that *seems* to work okay in my head. You'd use it simply as:
    PHP Code:
    $dtStart = new DateTime('November 11');
    $dtEnd = new DateTime('March 3');
    $dtTarget = new DateTime('February 12');
    printf('%s is between %s and %s?  %d' PHP_EOL,
        
    $dtTarget->format('F j'),
        
    $dtStart->format('F j'),
        
    $dtEnd->format('F j'),
        
    isDateBetween($dtTarget$dtStart$dtEnd)); 
    For example. Note there are no years here, but the implicit year is this year. If you add years, it will override the implicit which can constrain the window or open it wider. So if you were to base this on a time provided with a year, you'd need to strip the year out (or use mktime and then wrap that in a dateTime).
    You'd need to test that out quite a bit, especially with some wider and narrower windows. Best I can figure in my head here is that on a year by year basis this won't be a problem; the endtime should be good even if you provide years since a year override would still fit in to the comparisons.


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •