ฉันมี 2 วันใน PHP ฉันจะเรียกใช้วนรอบ foreach เพื่อผ่านทุกวันเหล่านั้นได้อย่างไร


207

ฉันเริ่มต้นด้วยวันที่และลงท้ายด้วย2010-05-01 2010-05-10ฉันจะทำซ้ำวันที่เหล่านั้นทั้งหมดใน PHP ได้อย่างไร

คำตอบ:


535

ต้องการ PHP5.3:

$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");
}

นี้ออกจะทุกวันในระยะเวลาที่กำหนดระหว่างและ$start $endหากคุณต้องการรวมเลข 10 ให้ตั้ง$endเป็น 11 คุณสามารถปรับรูปแบบตามที่คุณต้องการ ดูคู่มือการใช้งาน PHP สำหรับDatePeriod


2
ข่าวดี - มีแพทช์สำหรับการตั้งค่าสถานะเพื่อรวมวันที่สิ้นสุดที่ (ไขว้นิ้ว) จะทำให้เป็นเวอร์ชันในอนาคต
ทักทาย

8
$begin->setTime(0,0); $end->setTime(12,0);หรือเริ่มต้นด้วยเวลาของวันของวันที่เริ่มต้นเป็นเวลาใด ๆ ภายหลังจากวันที่สิ้นสุดจะรวมถึงวันที่สิ้นสุดในลูป ไม่ใช่ตัวแก้ไขที่มีสไตล์ที่สุด แต่เป็นตัวเลือกที่ดีที่สุดตราบใดที่ไม่มีธงที่เหมาะสม
Chris

31
หากคุณต้องการรวมวันที่สิ้นสุดลงในช่วงเวลาของคุณคุณสามารถทำได้: $ end = $ end-> modified ('+1 วัน');
JulienITARD

3
เป็นไปได้ไหมที่จะใช้สิ่งนี้ แต่กลับด้านเพื่อย้อนกลับไปในประวัติศาสตร์?
จอน

3
@JulienITARD ว่าเป็นความคิดที่ดี แต่สง่างามกว่านั้นคือ $ end-> add ($ interval) เพราะมันตอบสนองโดยตรงกับช่วงเวลาที่เปลี่ยนแปลงไป)
GDY

92

รวมถึงวันสุดท้าย

$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");
}

หากคุณไม่ต้องการวันที่สุดท้ายให้ลบออก=จากเงื่อนไข


1
โปรดทราบว่า$beginจะแตกต่างกันหลังจากลูป new DateTime( "2015-07-03" )วงนี้ปรับเปลี่ยนวัตถุที่สร้างขึ้นโดย ดังนั้นทำไมคุณควรใช้ DateTimeImmutable เวอร์ชัน แต่คุณต้องมีการแก้ไขเพิ่มเติมสำหรับการใช้งาน
Henk Poley

40

การแปลงเป็นเวลา unix ทำให้การคำนวณวันที่ทางคณิตศาสตร์ง่ายขึ้นใน php:

$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 กับเขตเวลาที่มี DST ตรวจสอบให้แน่ใจว่าได้เพิ่มเวลาที่ไม่ใช่ 23:00, 00:00 หรือ 1:00 เพื่อป้องกันวันที่ข้ามหรือทำซ้ำ


4
ฉันไม่ชอบรูปลักษณ์ของ 86400 ฉันเข้าใจว่าเป็น 60 * 60 * 24 แต่ก็ยัง ... บางสิ่งบางอย่างเกี่ยวกับเรื่องนี้ทำให้ฉันหงุดหงิด
MikeD

13
ในกรณีนี้มันใช้งานได้ แต่ถ้ามีการสลับระหว่างเวลาปกติกับการประหยัดแสงแดดมันจะล้มเหลวเพราะมี 90000 วันที่สองที่คุณจะมีสองครั้งในวงวนของคุณ ...
oezi

2
ไมค์สิ่งที่ดีที่สุดที่ต้องทำคือตั้งค่าคงที่และตั้งชื่อเป็น "วัน" เพื่อให้อ่านง่ายขึ้น
นักพัฒนา Pixel

5
สิ่งนี้จะประสบกับปัญหาการออมในเวลากลางวัน เมื่อคุณข้ามจุดประหยัดเวลากลางวันมันจะทำให้เมามากขึ้น 12:00 am ไม่ใช่ 12:00 am ทั้งสองด้านของเวลา
Eric Cope

1
รหัสนี้ใช้ (แต่ละรหัสที่มี 86400 วินาทีต่อวัน) มีปัญหากับการปรับเวลาตามฤดูกาล! ด้วยการปรับเวลาตามฤดูกาลบางวันใช้เวลาเพียง 23 ชั่วโมงและบาง 25 ชั่วโมง
sbrbot

20

คัดลอกจากตัวอย่าง php.net สำหรับช่วงรวม :

$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>";
}

นี่คือคำตอบที่ดีที่สุดและสมบูรณ์ที่สุด หายไปเพียงคำอธิบายบางส่วนของค่า DateInterval P1D ดังนั้นนี่คือตัวอย่างนักออกแบบช่วงเวลาสองวัน: P2D สองวินาที: PT2S หนึ่งสัปดาห์และสิบนาที: P1WT10M Y สำหรับปี M สำหรับเดือน W สำหรับวัน W สำหรับสัปดาห์ สิ่งเหล่านี้ถูกแปลงเป็นวันดังนั้นไม่สามารถใช้ร่วมกับ D. H เป็นชั่วโมง M สำหรับนาที S เป็นวินาที
Orcra

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);

หรือ

$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
ดูเหมือนว่าวิธีนี้จะช้ากว่าคำตอบที่ยอมรับ (ไม่ได้วิ่งบ้าง: ช้าลง 100% สำหรับการวนซ้ำ 60 ครั้ง) แต่ฉันเลือกอันนี้สำหรับความเข้ากันได้ย้อนยุคสำหรับ plateforms โฮสติ้งแบบเก่า
Ifnot

7

นี่คืออีกง่าย -

/**
 * 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;
}

ตัวอย่าง:

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

ใช้ฟังก์ชั่นนี้: -

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;
        }

การใช้งาน / ฟังก์ชั่นการโทร: -

เพิ่มขึ้นหนึ่งวัน: -

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

เพิ่มขึ้นตามเดือน: -

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

ใช้พารามิเตอร์ตัวที่สามหากคุณต้องการกำหนดรูปแบบวันที่: -

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

2

นี่คือวิธี:

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

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

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

     $dtStart->addDay();
 }

ผลลัพธ์ของ $ weekends ในอีกไม่กี่วันหยุดสุดสัปดาห์!


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"));
}

คุณสามารถย้ำเช่นนี้นอกจากนี้$_POST['date']สามารถบุ๋มจาก app หรือเว็บไซต์ของคุณแทนคุณยังสามารถวางสายของคุณที่นี่$_POST['date'] "21-12-2019"ทั้งสองจะทำงาน


0

หากคุณใช้ Laravel และต้องการใช้ Carbon โซลูชันที่ถูกต้องจะเป็นดังนี้:

$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");
}

อย่าลืมเพิ่ม:

  • ใช้ Carbon \ Carbon;
  • ใช้ Carbon \ CarbonPeriod;

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)));
    }

?>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.