Skip to content

Instantly share code, notes, and snippets.

@JacobBennett
Created December 31, 2019 17:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JacobBennett/66eb73132c732dfbc1a13c814497f9ab to your computer and use it in GitHub Desktop.
Save JacobBennett/66eb73132c732dfbc1a13c814497f9ab to your computer and use it in GitHub Desktop.
A little mess I had on my hands today
<?php
$start = Carbon::parse('2019-12-24');
$end = Carbon::parse('2020-01-04');
$birthDate = Carbon::parse('1985-12-24')->addDays(random_int(0,6));
// figure out if month and day of birthDate is between the $start and $end
@midnite81
Copy link

@ahinkle
Copy link

ahinkle commented Dec 31, 2019

@midnite81, your solution doesn't work if the birthdate is the following year.

        $start = Carbon::parse('2019-12-24');
        $end   = Carbon::parse('2020-01-04');
        $birthDate = Carbon::parse('1985-01-03');

        $birthDateCurrent = Carbon::create(Carbon::now()->format('Y'),
            $birthDate->month, $birthDate->day);
        return $birthDateCurrent->greaterThanOrEqualTo($start)
            && $birthDateCurrent->lessThanOrEqualTo($end);

		// false

@midnite81
Copy link

@ahinkle You are correct - I've updated it. I think that should work now - but it's New Year's Eve ... so haven't thoroughly tested.

@ahinkle
Copy link

ahinkle commented Dec 31, 2019

Works for overlap birthdays (say on Jan 3rd)

    public function test_is_birthday_week()
    {
        $start = Carbon::parse('2019-12-24');
        $end = Carbon::parse('2020-01-04');
        
        $birthday = Carbon::parse('1985-12-24')->setYear(date('Y'));
        $birthdayThisWeek = Carbon::parse('1990-01-03')->setYear(date('Y'));
        $nonBirthday = Carbon::parse('2000-07-01')->setYear(date('Y'));
        
        // new year overlaps
        if ($birthday->format('md') < $end->format('md')) $birthday->addYear();
        if ($birthdayThisWeek->format('md') < $end->format('md')) $birthdayThisWeek->addYear();
        if ($nonBirthday->format('md') < $end->format('md')) $nonBirthday->addYear();

        $birthWeek = $birthday->between($start, $end);
        $birthWeekNextYear = $birthdayThisWeek->between($start, $end);
        $nonBirthdayWeek = $nonBirthday->between($start, $end);

    
        $this->assertTrue($birthWeek);
        $this->assertTrue($birthWeekNextYear);
        $this->assertFalse($nonBirthdayWeek);
    }

@phppirate
Copy link

phppirate commented Dec 31, 2019

First Attempt at this

function birthdayIsBetween($birthday, $start, $end)
{
    $birthday = $birthday->copy()->setYear($start->format("Y"));
    $birthdayNext = $birthday->copy()->setYear($end->format("Y"));

    return $birthday->isBetween($start, $end) ||
           $birthdayNext->isBetween($start, $end);
}

Note: This works for birthdays in week and new year overlap but does not handle if your "between dates" being in more than 2 years.

@JacobBennett
Copy link
Author

JacobBennett commented Dec 31, 2019

@midnite81 @ahinkle and @phppirate it looks like you guys all arrived at a pretty similar solution. This works great actually! Smart thinking. I went a little bit different route which was to get a format('md') of all the dates I wanted to check, and then see if the format('md') of the date I want to check is contained in that collection.

Here is the pseudo code version.

$start = today()->startOfWeek();
 
$dates = collect(range(0, 6))->map(function ($days) use ($start) {
            return $start->clone()->addDays($days)->format('md');
        });

$dates->contains($birthday->format('md'));

I'm storing that set of $dates on the object when iterating over the users to check if anyone has a birthday, so I don't have to generate the range every time. Works well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment