PHP 2 tarihleri ​​var, nasıl o gün boyunca gitmek için bir foreach döngü çalıştırabilirsiniz?


207

Bir tarihle başlıyorum 2010-05-01ve ile bitiyorum 2010-05-10. PHP'deki tüm bu tarihleri ​​nasıl yineleyebilirim?

Yanıtlar:


535

PHP5.3 gerektirir:

$begin = new DateTime('2010-05-01');
$end = new DateTime('2010-05-10');

$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);

foreach ($period as $dt) {
    echo $dt->format("l Y-m-d H:i:s\n");
}

Bu, $startve arasında belirtilen sürede tüm günleri çıktılar $end. 10'u dahil etmek istiyorsanız, $end11'e ayarlayın . Biçimi isteğinize göre ayarlayabilirsiniz. DatePeriod için PHP Kılavuzuna bakın .


2
iyi haber - bir bayrağın (parmak çarpı işareti) gelecekteki bir versiyona dönüştüreceği bitiş tarihini içerecek şekilde ayarlanması için bir yama var.
salat

8
$begin->setTime(0,0); $end->setTime(12,0);veya başlangıç ​​tarihinin günün saatiyle bitiş tarihinin bitiş tarihinden sonraki herhangi bir saatte başlangıç ​​durumuna getirmek, bitiş tarihini döngüde içerecektir. En şık düzeltme değil, ancak uygun bir bayrak olmadığı sürece en iyi seçenektir.
Chris

31
Bitiş tarihini aralığınıza eklemek istiyorsanız, şunları yapabilirsiniz: $ end = $ end-> change ('+1 gün');
JulienITARD

3
Tarihte geri dönmek için bunu kullanmak ama tersine çevirmek mümkün mü?
Jon

3
@JulienITARD bu oldukça iyi bir fikir ama daha zarif olacak $ end-> add ($ aralık) çünkü değişmiş bir aralığa doğrudan yanıt verir;)
GDY

92

Buna son tarih de dahildir

$begin = new DateTime( "2015-07-03" );
$end   = new DateTime( "2015-07-09" );

for($i = $begin; $i <= $end; $i->modify('+1 day')){
    echo $i->format("Y-m-d");
}

Son tarihe ihtiyacınız yoksa, sadece =durumdan kaldırın .


1
Döngüden sonra $beginbunun farklı olacağını unutmayın . Bu döngü, tarafından oluşturulan nesneyi değiştirir new DateTime( "2015-07-03" ). Bu nedenle DateTimeImmutable sürümlerini kullanmalısınız. Ancak bunları kullanmak için başka değişikliklere ihtiyacınız var.
Henk Poley

40

Unix zaman damgalarına dönüştürmek, php'de tarih matematiğini kolaylaştırır:

$startTime = strtotime( '2010-05-01 12:00' );
$endTime = strtotime( '2010-05-10 12:00' );

// Loop between timestamps, 24 hours at a time
for ( $i = $startTime; $i <= $endTime; $i = $i + 86400 ) {
  $thisDate = date( 'Y-m-d', $i ); // 2010-05-01, 2010-05-02, etc
}

PHP'yi DST içeren bir saat dilimiyle kullanırken, atlama veya yinelenen günlere karşı korumak için 23:00, 00:00 veya 1:00 olmayan bir zaman eklediğinizden emin olun.


4
Bu 86400'ün görünümünü sevmiyorum. 60 * 60 * 24 olduğunu anlıyorum, ama yine de ... bu konuda bir şey beni rahatsız ediyor.
MikeD

13
Bu durumda, işe yarıyor, ancak normal ve güneş ışığından tasarruf süresi arasında bir geçiş varsa, başarısız olacak çünkü
döngünüzde

2
Mike, yapılacak en iyi şey bir sabit kurmak ve "DAY" olarak adlandırmak, böylece okumak çok daha kolay hale geliyor.
Pixel Developer

5
Bu, gün ışığından yararlanma sorunları yaşayacaktır. Gün ışığından yararlanma saatini geçtiğinizde berbat olur. Saat 12:00, zamanın her iki tarafında 12:00 değil.
Eric Cope

1
Bu kod (günde 86400 saniyelik her kod) gün ışığından yararlanma konusunda sorun yaşıyor! Gün ışığından yararlanma bazı günler sadece 23 saat ve 25 saat sürer.
sbrbot

20

Kapsayıcı aralık için php.net örneğinden kopyalayın :

$begin = new DateTime( '2012-08-01' );
$end = new DateTime( '2012-08-31' );
$end = $end->modify( '+1 day' ); 

$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);

foreach($daterange as $date){
    echo $date->format("Ymd") . "<br>";
}

bu en iyi ve en eksiksiz cevaptır. DateInterval değeri P1D'nin sadece bazı açıklamalarını kaçırdığımız için bazı Dönem Tanımlayıcı örnekleri İki gün: P2D İki saniye: PT2S Bir hafta on dakika: P1WT10M Y, yıllarca D, haftalarca W günler için. Bunlar günlere dönüştürülür, bu nedenle D
saatiyle

15
$startTime = strtotime('2010-05-01'); 
$endTime = strtotime('2010-05-10'); 

// Loop between timestamps, 1 day at a time 
$i = 1;
do {
   $newTime = strtotime('+'.$i++.' days',$startTime); 
   echo $newTime;
} while ($newTime < $endTime);

veya

$startTime = strtotime('2010-05-01'); 
$endTime = strtotime('2010-05-10'); 

// Loop between timestamps, 1 day at a time 
do {
   $startTime = strtotime('+1 day',$startTime); 
   echo $startTime;
} while ($startTime < $endTime);

2
Bu çözüm kabul edilen cevaptan daha yavaş görünüyor (bazı tezgahlar çalıştırıldı: 60 tekrar için% 100 daha yavaş). Ama ben eski barındırma plakaları için retro uyumluluk için bunu seçin.
değilse

7

İşte bir başka basit -

/**
 * Date range
 *
 * @param $first
 * @param $last
 * @param string $step
 * @param string $format
 * @return array
 */
function dateRange( $first, $last, $step = '+1 day', $format = 'Y-m-d' ) {
    $dates = [];
    $current = strtotime( $first );
    $last = strtotime( $last );

    while( $current <= $last ) {

        $dates[] = date( $format, $current );
        $current = strtotime( $step, $current );
    }

    return $dates;
}

Misal:

print_r( dateRange( '2010-07-26', '2010-08-05') );

Array (
    [0] => 2010-07-26
    [1] => 2010-07-27
    [2] => 2010-07-28
    [3] => 2010-07-29
    [4] => 2010-07-30
    [5] => 2010-07-31
    [6] => 2010-08-01
    [7] => 2010-08-02
    [8] => 2010-08-03
    [9] => 2010-08-04
    [10] => 2010-08-05
)

5

Bu işlevi kullan: -

function dateRange($first, $last, $step = '+1 day', $format = 'Y-m-d' ) {
                $dates = array();
                $current = strtotime($first);
                $last = strtotime($last);

                while( $current <= $last ) {    
                    $dates[] = date($format, $current);
                    $current = strtotime($step, $current);
                }
                return $dates;
        }

Kullanım / fonksiyon çağrısı: -

Bir gün artış: -

dateRange($start, $end); //increment is set to 1 day.

Aya Göre Artış: -

dateRange($start, $end, "+1 month");//increase by one month

tarih biçimini ayarlamak istiyorsanız üçüncü parametreyi kullanın: -

   dateRange($start, $end, "+1 month", "Y-m-d H:i:s");//increase by one month and format is mysql datetime

2

İşte bir yol:

 $date = new Carbon();
 $dtStart = $date->startOfMonth();
 $dtEnd = $dtStart->copy()->endOfMonth();

 $weekendsInMoth = [];
 while ($dtStart->diffInDays($dtEnd)) {

     if($dtStart->isWeekend()) {
            $weekendsInMoth[] = $dtStart->copy();
     }

     $dtStart->addDay();
 }

$ WeekendsInMoth, hafta sonu günlerinin bir dizisidir!


0
$date = new DateTime($_POST['date']);
$endDate = date_add(new DateTime($_POST['date']),date_interval_create_from_date_string("7 days"));

while ($date <= $endDate) {
    print date_format($date,'d-m-Y')." AND END DATE IS : ".date_format($endDate,'d-m-Y')."\n";
    date_add($date,date_interval_create_from_date_string("1 days"));
}

Bu şekilde de yineleyebilirsiniz $_POST['date'], Uygulamanızdan veya web sitenizden göçük olabilir Bunun yerine $_POST['date']dizenizi buraya da yerleştirebilirsiniz "21-12-2019". Her ikisi de işe yarayacak.


0

Laravel kullanıyorsanız ve Carbon kullanmak istiyorsanız doğru çözüm aşağıdaki gibi olur:

$start_date = Carbon::createFromFormat('Y-m-d', '2020-01-01');
$end_date = Carbon::createFromFormat('Y-m-d', '2020-01-31');

$period = new CarbonPeriod($start_date, '1 day', $end_date);

foreach ($period as $dt) {
 echo $dt->format("l Y-m-d H:i:s\n");
}

Eklemeyi unutmayın:

  • Carbon \ Carbon kullanın;
  • Carbon \ CarbonPeriod kullanın;

0
<?php

    $start_date = '2015-01-01';
    $end_date = '2015-06-30';

    while (strtotime($start_date) <= strtotime($end_date)) {
        echo "$start_daten";
        $start_date = date ("Y-m-d", strtotime("+1 days", strtotime($start_date)));
    }

?>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.