如何从PHP中的数组+打印名称获取最接近的生日日期

如何从PHP中的数组+打印名称获取最接近的生日日期

问题描述:

Started to use PHP about 2 weeks ago,got first problems =D

Can't figure how to get my task done.

Program have to give next upcoming birthday and name.Thanks in advance

How to make this programm print out something like :

Jessy Pinkmann 2017-09-11

<?php

$today=new DateTime();


$Bdays = array
(
    array("Lucienne Adkisson",date_create("2017-10-17")),            //0    //  Y/M/D
    array("Sheryll Nestle",date_create("2017-02-16")),            //1
    array("Tim Pittman",date_create("2017-07-29")),           //2
    array("Elmer Letts",date_create("2017-12-01")),                 //3
    array("Gino Massengale",date_create("2017-04-16")),              //4
    array("Jeremy Wiggs ",date_create("2017-09-17")),            //5
    array("Julian Bulloch ",date_create("2017-06 -21")),             //6
    array("Joella Hinshaw  ",date_create("2017-06-25")),                //7
    array("Mamie Burchill  ",date_create("2017-11-15")),                    //8
    array("Constance Segers  ",date_create("2017-06-30")),                //9
    array("Jessy Pinkmann",date_create("2017-09-11")),             //10
    array("Dudley Currie",date_create("2017-02-10"))             //11
);


for ($x =0; $x <= 11; $x++ ){


$diff=date_diff($today,$Bdays[$x][1]);
echo $diff->format("  %R%a");

}

?>

大约2周前开始使用PHP,遇到第一个问题= D p>

无法确定如何完成任务。 p>

程序必须提供下一个即将到来的生日和名字。提前谢谢 p>

如何制作 这个程序打印出类似的东西: p>

Jessy Pinkmann 2017-09-11 p>

 &lt;?php 
 
 $ today =  new DateTime(); 
 
 
 $ Bdays = array 
(
 array(“Lucienne Adkisson”,date_create(“2017-10-17”)),// 0 // Y / M / D \  n array(“Sheryll Nestle”,date_create(“2017-02-16”)),// 1 
数组(“Tim Pittman”,date_create(“2017-07-29”)),// 2 
数组 (“Elmer Letts”,date_create(“2017-12-01”)),// 3 
数组(“Gino Massengale”,date_create(“2017-04-16”)),// 4 
数组(“  Jeremy Wiggs“,date_create(”2017-09-17“)),// 5 
数组(”Julian Bulloch“,date_create(”2017-06 -21“)),// 6 
数组(”Joella Hinshaw“  ”,date_create( “2017年6月25日”)),  // 7 
 array(“Mamie Burchill”,date_create(“2017-11-15”)),// 8 
 array(“Constance Segers”,date_create(“2017-06-30”)),//  9 
数组(“Jessy Pinkmann”,date_create(“2017-09-11”)),// 10 
数组(“Dudley Currie”,date_create(“2017-02-10”))// 11 
  ); 
 
 
for($ x = 0;  $ x&lt; = 11;  $ x ++){
 
 
 $ diff = date_diff($ today,$ Bdays [$ x] [1]); 
echo $ diff-&gt; format(“%R%a”); 
 
  } 
 
?&gt; 
  code>  pre> 
  div>

You can try this code:

<?php
$today=new DateTime();
$count = 0;


$Bdays = array(
    array("Lucienne Adkisson",date_create("2017-10-17")),            
    array("Sheryll Nestle",date_create("2017-02-16")),            
    array("Tim Pittman",date_create("2017-07-29")),           
    array("Elmer Letts",date_create("2017-12-01")),                 
    array("Gino Massengale",date_create("2017-04-16")),              
    array("Jeremy Wiggs ",date_create("2017-09-17")),            
    array("Julian Bulloch ",date_create("2017-06 -21")),             
    array("Joella Hinshaw  ",date_create("2017-06-25")),               
    array("Mamie Burchill  ",date_create("2017-11-15")),                   
    array("Constance Segers  ",date_create("2017-06-30")),                
    array("Jessy Pinkmann",date_create("2017-09-11")),             
    array("Dudley Currie",date_create("2017-02-10"))             
);



for($x = 0, $len = count($Bdays); $x < $len; $x++){

    $diff = date_diff($today, $Bdays[$x][1]);
   
    $difference = $diff->format("  %R%a");
    if($difference > 0){
        if($count == 0){
            $smallest_diff = $difference;
        }
        $count++;
        if($difference < $smallest_diff){
            $smallest_diff = $difference;
            $closest_index = $x;
        }
    }
}

echo "The upcoming birtday person is: <b>" . $Bdays[$closest_index][0] . '</b> and his birthday is on: <b>' . date_format($Bdays[$closest_index][1], "Y/m/d") . '</b>';

?>

It's woking fine. Here is the output:

enter image description here

</div>

I have restructured some of your code.

<?php
$today = date("Y-m-d");

$Bdays = array
(
    array("Lucienne Adkisson", "2017-10-17"),
    array("Sheryll Nestle", "2017-02-16"),
    array("Tim Pittman", "2017-07-29"),
    array("Elmer Letts", "2017-12-01"),
    array("Gino Massengale", "2017-04-16"),
    array("Jeremy Wiggs", "2017-09-17"),
    array("Julian Bulloch", "2017-06 -21"),
    array("Joella Hinshaw", "2017-06-25"),
    array("Mamie Burchill", "2017-11-15"),
    array("Constance Segers", "2017-06-30"),
    array("Jessy Pinkmann", "2017-09-11"),
    array("Dudley Currie", "2017-02-10")
);


$tmp = 366;
$closest = ["", 0];
for ($i = 0; $i < count($Bdays); $i++)
{
    if (abs(strtotime($today) - strtotime($Bdays[$i][1])) / 86400 < $tmp)
    {
        $tmp = abs(strtotime($today) - strtotime($Bdays[$i][1])) / 86400;
        $closest = [$Bdays[$i][0], $Bdays[$i][1]];
    }
}
?>

$tmp is set to have no value and be 366 days. This is the variable that will store the closest date to today's date. I have also changed the for loop to use the count function which means that if you add more dates to $Bdays then it will iterate more times for the for loop.

$closest stores the name and birthday of the closest date to the today.

The abs function will convert negative numbers to positive numbers. This is because if you had a difference of -138 for instance, that would be less than 38 even though that would mean the date was 100 days further away, just simply because negative numbers are lower.

Update

I have updated the code. This new code will now work regardless of the year. I changed it because obviously, birthdays don't count the year. This will be useful if someone's birthday was something like "2015-04-10" will count as the closest as that is only 1 day away, even though it is 2 years and 1 day away.

I have written a comment in the code. What this means is that if you want to take the years into account then set $format = "Y-m-d" but if you don't want to take years into account then set $format = "m-d" and this will just subtract the difference between months and the days.

<?php
$format = "Y-m-d"; // change to "m-d" to ignore years
$today = date($format);

$Bdays = array
(
    array("Lucienne Adkisson", strtotime("2017-10-17")),
    array("Sheryll Nestle", strtotime("2017-02-16")),
    array("Tim Pittman", strtotime("2017-07-29")),
    array("Elmer Letts", strtotime("2017-12-01")),
    array("Gino Massengale", strtotime("2016-04-16")),
    array("Jeremy Wiggs", strtotime("2017-09-17")),
    array("Julian Bulloch", strtotime("2017-06 -21")),
    array("Joella Hinshaw", strtotime("2017-06-25")),
    array("Mamie Burchill", strtotime("2017-11-15")),
    array("Constance Segers", strtotime("2017-06-30")),
    array("Jessy Pinkmann", strtotime("2017-09-11")),
    array("Dudley Currie", strtotime("2017-02-10"))
);


$tmp = 366;
$closest = ["", 0];
for ($i = 0; $i < count($Bdays); $i++)
{
    if (abs($today - date($format, $Bdays[$i][1])) < $tmp)
    {
        $tmp = abs($today - date($format, $Bdays[$i][1]));
        $closest = [$Bdays[$i][0], date("Y-m-d", $Bdays[$i][1])];
    }
}
?>

try this:

DateTime offers you a diff method, which is easy to use. If a precision of days is enough, you can use the days property of that result to compare your dates. Then you have to store the index of the lowest delta and in the end you can fetch the according element in the array

<?php

$today = new DateTime();

$Bdays = array
(
    array("Lucienne Adkisson", date_create("2017-10-17")),
    array("Sheryll Nestle", date_create("2017-02-16")),
    array("Tim Pittman", date_create("2017-07-29")),
    array("Elmer Letts", date_create("2017-12-01")),
    array("Gino Massengale", date_create("2017-04-16")),
    array("Jeremy Wiggs ", date_create("2017-09-17")),
    array("Julian Bulloch ", date_create("2017-06 -21")),
    array("Joella Hinshaw  ", date_create("2017-06-25")),
    array("Mamie Burchill  ", date_create("2017-11-15")),
    array("Constance Segers  ", date_create("2017-06-30")),
    array("Jessy Pinkmann", date_create("2017-09-11")),
    array("Dudley Currie", date_create("2017-02-10"))
);

$len = count($Bdays);
$minDiff = PHP_INT_MAX;
$minIndex = -1;

for ($i = 0; $i < $len; $i++) {
    $diff = $today->diff($Bdays[$i][1]);

    if ($diff->days < $minDiff) {
        $minIndex = $i;
        $minDiff = $diff->days;
    }
}

print_r($Bdays[$minIndex]);

This is a example with the "Arrayy"-class. "$currentDate" is fixed in the example, so that the result is the same every day.

Unit-Test: https://github.com/voku/Arrayy/blob/master/tests/ArrayyTest.php#L2511

Install: composer require voku/arrayy

Example:

$birthDates = array(
    array('Lucienne Adkisson', date_create('2017-10-17')),
    array('Sheryll Nestle', date_create('2017-02-16')),
    array('Tim Pittman', date_create('2017-07-29')),
    array('Elmer Letts', date_create('2017-12-01')),
    array('Gino Massengale', date_create('2017-04-16')),
    array('Jeremy Wiggs', date_create('2017-09-17')),
    array('Julian Bulloch', date_create('2017-06 -21')),
    array('Joella Hinshaw', date_create('2017-06-25')),
    array('Mamie Burchill', date_create('2017-11-15')),
    array('Constance Segers', date_create('2017-06-30')),
    array('Jessy Pinkmann', date_create('2017-09-11')),
    array('Dudley Currie', date_create('2017-02-10')),
);

$birthDatesAraayy = new Arrayy($birthDates);
$currentDate = new \DateTime('2017-09-11');
$format = 'Y-m-d H:i:s';

/**
 * sort by date - helper-function
 *
 * @param array $a
 * @param array $b
 *
 * @return int
 */
$closureSort = function ($a, $b) use ($format) {
  /* @var $aDate \DateTime */
  /* @var $bDate \DateTime */
  $aDate = $a[1];
  $bDate = $b[1];

  if ($aDate->format($format) === $bDate->format($format)) {
    return 0;
  }

  return $aDate->format($format) > $bDate->format($format) ? -1 : 1;
};

/**
 * reduce by date - helper-function
 *
 * @param array $resultArray
 * @param array $value
 *
 * @return array
 */
$closureReduce = function ($resultArray, $value) use ($currentDate) {
  /* @var $valueDate \DateTime */
  $valueDate = $value[1];

  $valueDateInterval = $currentDate->diff($valueDate);

  if ($valueDateInterval->format('%R%a') >= 0) {
    $resultArray['thisYear'][] = $value;
  } else {
    $value[1] = $valueDate->modify('+1 year');

    $resultArray['nextYear'][] = $value;
  }

  return $resultArray;
};

//
// reduce && sort the array
//

/* @var $resultMatch Arrayy|Arrayy[] */
$resultMatch = $birthDatesAraayy->reduce($closureReduce);

$thisYear = $resultMatch['thisYear']->customSortValues($closureSort);
$nextYear = $resultMatch['nextYear']->customSortValues($closureSort);

$resultMatch = $nextYear->reverse()->mergePrependNewIndex($thisYear->reverse()->getArray());

//
// check the result
//

self::assertEquals(
    array(
        array('Jessy Pinkmann', date_create('2017-09-11')),
        array('Jeremy Wiggs', date_create('2017-09-17')),
        array('Lucienne Adkisson', date_create('2017-10-17')),
        array('Mamie Burchill', date_create('2017-11-15')),
        array('Elmer Letts', date_create('2017-12-01')),
        array('Dudley Currie', date_create('2018-02-10')),
        array('Sheryll Nestle', date_create('2018-02-16')),
        array('Gino Massengale', date_create('2018-04-16')),
        array('Julian Bulloch', date_create('2018-06 -21')),
        array('Joella Hinshaw', date_create('2018-06-25')),
        array('Constance Segers', date_create('2018-06-30')),
        array('Tim Pittman', date_create('2018-07-29')),
    ),
    $resultMatch->getArray()
);