6
votes

Diviser une gamme de dates en blocs contigus

Dupliqué possible: strong>
Vérifier les dates consécutives dans un ensemble et retour comme Gamme P>

J'ai une gamme de dates obtenues à partir d'une requête MySQL. J'ai besoin de diviser le tableau en plusieurs tableaux afin que les dates de chaque matrice soient contiguës. P>

Donc, si je commence par P>

$firstdatearray = array("2013-05-05", "2013-05-06", "2013-05-07", "2013-05-08");
$seconddatearray = array("2013-06-29", "2013-06-30", "2013-07-01");


3 commentaires

Vous n'avez aucune idée où commencer? Je parie que vous avez au moins une idée de ce que vous pourriez faire.


Donc, vous devriez vraiment essayer de faire quelque chose puis de poser la question lorsque vous rencontrez des problèmes de mise en œuvre spécifiques.


Similaire, adaptable: Stackoverflow.com/questions/8461543/...


7 Réponses :


0
votes

Je ne peux pas vous aider avec du code de acutal, mais vous pourriez faire quelque chose comme ceci:

  • Trouvez des points de départ et des points finaux des gammes
  • comptez les étapes entre entre (1 étape = 1 jour)
  • Utilisez mktime (ou DateTime ou Strftime) pour calculer la date de fin en fonction de la date de début + des jours d'étape)
  • Imprimez comme vous le souhaitez.

0 commentaires

0
votes

Toutes les dates que vous avez sont la même année. Vous pouvez convertir chaque date au nombre de la journée de cette année.

Ensuite, vous auriez une gamme de chiffres. Pour ce tableau, vous pouvez simplement faire comme indiqué ici: P>


0 commentaires

0
votes

Cela fonctionnera:

$datearray = array("2013-05-05", "2013-05-06", "2013-05-07", "2013-05-08", "2013-06-19", "2013-06-20", "2013-06-21");
$current_date_array_index = 0;
$dates = array();

for($i=0,$c=count($datearray);$i<$c;$i++){
    if(strtotime($dates[$current_date_array_index][count($dates[$current_date_array_index])-1]." +1 day") != strtotime($datearray[$i])){
        $current_date_array_index++;
    }
    $dates[$current_date_array_index][] = $datearray[$i];
}

foreach($dates as $date){
    if(count($date) == 1){
        $output[] = date('j M',strtotime($date[0]));
    }else{
        $output[] = date('j',strtotime($date[0]))." - ".date('j M',strtotime($date[count($date)-1]));
    }
}

echo implode($output,", "); // output: 5 - 8 May, 19 - 21 Jun


0 commentaires

0
votes

Essayez quelque chose comme ceci: xxx

Remarque: je n'ai pas testé le code ci-dessus afin qu'il puisse contenir des fautes de frappe.

Je suis simplement itération sur chaque jour dans le Array, et déterminer s'il s'agit d'une journée continue de la veille. Si tel est le cas, il est ajouté au même groupe, si ce n'est pas le cas, il est ajouté à un index de tableau différent. Vous devrez peut-être trier les dates après cela en utilisant une sorte de fonction de tri de php . Ensuite, itérez sur les groupes de matrices pour déterminer la plage de dates.


0 commentaires

5
votes

C'est la réponse de travail complète. (Profitez-en!) Strong>

Vous devrez faire boucle à travers chaque valeur en $ DIFTARRAY P>

5-8 May, 19-21 Jun


4 commentaires

Merci Mrbinky. Qui semble prometteur. Je travaille pour le développer pleinement dans ma demande maintenant. Je reviendrai quand j'ai plus de nouvelles.


C'était à peu près la "réponse de travail complète". Juste quelques petites choses et ça vole: je n'ai pas remarqué le sommet = "": ligne au début, alors j'ai réinventé cette roue moi-même. date ("m d", etc. dans le dernier $ out. = ligne m'a donné des dates arrière-front et toujours deux caractères. Changer à la date ("J m", etc. La liste des dates s'est terminée par une virgule, Alors j'ai utilisé Rtrim pour ranger ça.


Merci à @ mrbinky3000 pour une solution vraiment utile. C'était beaucoup moins douloureux que je m'attendais. Merci également à tous ceux qui ont pris la peine de regarder ça. Je suis sûr qu'il y a d'autres solutions de travail ici, mais c'était celui que j'ai couru avec.


Il y avait une autre question que j'ai trouvée une fois que j'ai commencé à utiliser la solution. Il n'a pas accueilli une seule date qui n'était pas contiguë de chaque côté. Je devais juste ajouter et plus un peu au si ... d'autre routine pour en tenir compte. Le code peut être vu en fonctionnement sur (par exemple) www.littlehotels.co.uk/spain/noves.php. Cliquez sur l'onglet Tarifs des chambres.



0
votes

Assumant PHP 5.3 ou plus.

Vous pouvez utiliser DateTime, dateInterval et un peu de travail algorithmique. P>

// create the same array but with DateTime objects to represent the dates
$dt_array = array_map(function ($e) { return new DateTime($e); }, $datearray);


$intervals = array();
$len_dt_array_m1 = count($dt_array) - 1;
if ($len_dt_array_m1 >= 0) {
    $current_interval = &$intervals[];
}

// now we traverse the array left to right.
// if the difference between the current date and the next is not +1 day, we assume a new interval has begun.
for ($i = 0; $i < $len_dt_array_m1; ++$i) {
    $current_dt = $dt_array[$i];
    $next_dt = $dt_array[$i+1];
    $diff = $current_dt->diff($next_dt);
    $current_interval[] = $current_dt->format('Y-m-d');
    if ($diff->days != 1 || $diff->invert != 0) {
        $current_interval = &$intervals[];
    }
}

// add last dt to the interval
if ($len_dt_array_m1 >= 0) {
    $current_interval[] = $dt_array[$len_dt_array_m1]->format('Y-m-d');
}

print_r($intervals);


0 commentaires

0
votes
class Date_Array_Split
{
    private $date_arrays = array();

    public function __construct( Array $dates, $split_into = 2 )
    {
        // Sort the array
        asort( $dates );

        // Calculate the array size to pass to array_chunk
        $size = ceil( count( $dates ) / $split_into );

        // Break up the array into pieces
        $dates = array_chunk( $dates, $size );

        $this->date_arrays = $dates;
    }

    public function __toString()
    {
        $string = array();  // Oh, the irony!

        // Iterate through the chunks
        foreach( $this->date_arrays as $date_array )
        {
            // Here's the oldest date in the chunk
            $date_min = min( $date_array );

            // Here's the newest date in the chunk
            $date_max = max( $date_array );

            // Default format for output
            $date_min_format = 'j M';

            // Accomodate the slight formatting change
            if( date( 'my', strtotime( $date_min ) ) === date( 'my', strtotime( $date_max ) ) )
            {
                // Moth and year are the same, omit the month
                $date_min_format = 'j';
            }

            // String-i-fy the dates for output
            $date_min_string = date( $date_min_format, strtotime( $date_min ) );
            $date_max_string = date( 'j M', strtotime( $date_max ) );

            // Add them to the output array
            $string[] = sprintf( '%s - %s', $date_min_string, $date_max_string );
        }

        // Return the output array separated by commas
        return implode( $string, ", " );
    }
}

$dates_array = array(
    "2013-05-05", 
    "2013-06-20", 
    "2013-05-07", 
    "2013-05-08", 
    "2014-05-09", 
    "2013-05-09", 
    "2013-06-19", 
    "2013-06-21"
);

$dates = new Date_Array_Split( $dates_array );

echo( $dates );
Output: 5 - 9 May, 19 Jun - 9 MayNote this is handling the years correctly.  That's why the output looks a bit odd.  Might want to account for that in the output.

0 commentaires