2017-08-07 4 views
0

Je suis en train de créer un calendrier d'événements. Les événements ont une date de début et une date de fin avec des dates stockées au format AAAAMMJJ. La liste des événements est visualisée par jour et les événements peuvent se dérouler sur une seule journée, ou s'étendre sur plusieurs jours.Trier Tableau par deux dates et règles

Les événements sont actuellement stockés dans un tableau, avec start_date et end_date

Comment puis-je:

  • Déplacer tous les événements qui commencent à la date actuelle au sommet du tableau .
  • puis trier les événements par date de début
  • trier ensuite les événements par date de fin

Have voir ce question, mais errant comment je peux construire la logique ci-dessus.

+0

Voulez-vous trois types de tri ou de toutes ces règles dans un ? –

Répondre

2

Déplacez tous les événements qui commencent à la date actuelle vers le haut du tableau, mais laissez les autres ordonnés tels quels!

$today = date('Ymd',strtotime('today')); 
usort($events,function($a,$b) use($today){ 
    if($a['start_date'] === $today && $b['start_date'] != $today){return -1;} 
    else if($b['start_date'] === $today && $a['start_date'] != $today){return 1;} 
    else {return strnatcmp($a['start_date'],$b['start_date']);} 
}); 

ou trier les événements par date de début

usort($events,function($a,$b){ 
    return strnatcmp($a['start_date'],$b['start_date']); 
}); 

ou trier les événements par date de fin

usort($events,function($a,$b){ 
    return strnatcmp($a['end_date'],$b['end_date']); 
}); 

EDIT Certaines données de test:

//example works best if today is 20170810 
$events = array(
    array(
    'name' => 'a', 
    'start_date' => '20170810', 
    'end_date' => '20170811', 
), 
    array(
    'name' => 'b', 
    'start_date' => '20170810', 
    'end_date' => '20170810', 
), 
    array(
    'name' => 'c', 
    'start_date' => '20170607', 
    'end_date' => '20170608', 
), 
    array(
    'name' => 'd', 
    'start_date' => '20170607', 
    'end_date' => '20170607', 
), 
    array(
    'name' => 'e', 
    'start_date' => '20170810', 
    'end_date' => '20170812', 
), 
    array(
    'name' => 'f', 
    'start_date' => '20170807', 
    'end_date' => '20170817', 
), 
); 
print_r($events); 

EDIT: Tous ensemble: Les événements sont classés par 'Sont-ils à partir d'aujourd'hui?', 'Start_date', 'date_fin'

$today = date('Ymd',strtotime('today')); 
usort($events,function($a,$b) use($today){ 
    //one of them starts today 
    if($a['start_date'] === $today && $b['start_date'] != $today){return -1;} 
    else if($b['start_date'] === $today && $a['start_date'] != $today){return 1;} 
    //both or neither start today, compare start_date 
    else { 
    if($a['start_date'] != $b['start_date']){ 
     //start_dates differ, order by them 
     return strnatcmp($a['start_date'],$b['start_date']); 
    } else { 
     //start dates are the same, order by end_date 
     return strnatcmp($a['end_date'],$b['end_date']); 
    } 
    } 
}); 

print_r($events); 

EDIT: En cours Les événements sont classés par « sont ? ils actuellement en cours « « start_date », « date_fin »

$today = date('Ymd',strtotime('today')); 
//function compares two elements to decide their position relative to each other 
usort($events,function($a,$b) use($today){ 
    //check if event is currently ongoing 
    //starts or ends today or today is between start and end 
    $ongoing = function($event) use($today){ 
    //this is the simplest form I could think of for the check 
    return (strnatcmp($event['start_date'],$today) < 1 && strnatcmp($today,$event['end_date']) < 1); 
    }; 
    $startstoday = function($event) use($today){ 
    return $event['start_date'] === $today; 
    }; 
    //only one of them is ongoing 
    if($ongoing($a) && !$ongoing($b)){return -1;} 
    else if($ongoing($b) && !$ongoing($a)){return 1;} 
    //both or neither are ongoing, compare start_date 
    else { 
    if($a['start_date'] != $b['start_date']){ 
     //start_dates differ, order by them 
     return strnatcmp($a['start_date'],$b['start_date']); 
    } else { 
     //start dates are the same, order by end_date 
     return strnatcmp($a['end_date'],$b['end_date']); 
    } 
    } 
}); 

print_r($events); 

EDIT: aUJOURD'HUI ET MISE eN cONTINU Les événements sont classés par « ? sont-ils à partir d'aujourd'hui », » Est ? Ils actuellement en cours », « start_date », « date_fin »

$today = date('Ymd',strtotime('today')); 
//function compares two elements to decide their position relative to each other 
usort($events,function($a,$b) use($today){ 
    //check if event is currently ongoing 
    //starts or ends today or today is between start and end 
    $ongoing = function($event) use($today){ 
    //this is the simplest form I could think of for the check 
    return (strnatcmp($event['start_date'],$today) < 1 && strnatcmp($today,$event['end_date']) < 1); 
    }; 
    //only one of them is ongoing 
    if($ongoing($a) && !$ongoing($b)){return -1;} 
    else if($ongoing($b) && !$ongoing($a)){return 1;} 
    //both are ongoing 
    else if($ongoing($a) && $ongoing($b)){ 
    //one starts today 
    if($a['start_date'] === $today && $b['start_date'] != $today){return -1;} 
    else if($b['start_date'] === $today && $a['start_date'] != $today){return 1;} 
    //both start today 
    else if($a['start_date'] === $today && $b['start_date'] === $today){ 
     return strnatcmp($a['end_date'],$b['end_date']); 
    } 
    //none starts today 
    else { 
     if($a['start_date'] != $b['start_date']){ 
     //start_dates differ, order by them 
     return strnatcmp($a['start_date'],$b['start_date']); 
     } else { 
     //start dates are the same, order by end_date 
     return strnatcmp($a['end_date'],$b['end_date']); 
     } 
    } 
    } else { 
    //neither are ongoing, compare start_date 
    if($a['start_date'] != $b['start_date']){ 
     //start_dates differ, order by them 
     return strnatcmp($a['start_date'],$b['start_date']); 
    } else { 
     //start dates are the same, order by end_date 
     return strnatcmp($a['end_date'],$b['end_date']); 
    } 
    } 
}); 

print_r($events); 

ET CE DERNIER PEUT ÊTRE SIMPLIFIÉE À:

$today = date('Ymd',strtotime('today')); 
usort($events,function($a,$b) use($today){ 
    $ongoing = function($event) use($today){ 
    return (strnatcmp($event['start_date'],$today) < 1 && strnatcmp($today,$event['end_date']) < 1); 
    }; 
    if($ongoing($a)){ 
    if(!$ongoing($b)){return -1;} 
    else { 
     if($a['start_date'] === $today && $b['start_date'] != $today){return -1;} 
     else if($b['start_date'] === $today && $a['start_date'] != $today){return 1;} 
    } 
    } else if($ongoing($b)){return 1;} 
    if($a['start_date'] != $b['start_date']){ 
    return strnatcmp($a['start_date'],$b['start_date']); 
    } else { 
    return strnatcmp($a['end_date'],$b['end_date']); 
    } 
}); 

print_r($events); 
+0

Merci Peter, logique - n'a pas pensé à appliquer chaque type après l'autre. – addedlovely

+1

@addedlovely Gardez à l'esprit que chaque tri annule les précédents. Vouliez-vous seulement un trieur avec les trois règles appliquées dans l'ordre décroissant? –

+1

@addedlovely J'ai ajouté des solutions combinant toutes les règles et comptabilisant les événements en cours. –