Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> PHP

สร้าง Array วันที่ระหว่างสองวันที่ใน PHP

ฟังก์ชันสร้าง Array ของวันที่ทุกวันระหว่าง Start Date และ End Date

ฟังก์ชันมาตรฐาน (DateTime - แนะนำ PHP 5.2+)

/**
 * สร้าง Array วันที่ระหว่างสองวันที่ (Inclusive)
 * 
 * @param string $startDate  เริ่มต้น (Y-m-d หรือ รูปแบบที่ strtotime รองรับ)
 * @param string $endDate    สิ้นสุด
 * @param string $format     รูปแบบ Output (default: Y-m-d)
 * @return array             Array ของ Date String
 */
function getDateRange(string $startDate, string $endDate, string $format = 'Y-m-d'): array {
    $start = new DateTime($startDate);
    $end = new DateTime($endDate);
    
    // Validate
    if ($start > $end) {
        throw new InvalidArgumentException('Start date must be before or equal to end date');
    }
    
    $dates = [];
    $interval = new DateInterval('P1D'); // 1 Day
    $period = new DatePeriod($start, $interval, $end->modify('+1 day')); // Inclusive
    
    foreach ($period as $date) {
        $dates[] = $date->format($format);
    }
    
    return $dates;
}

// ใช้งาน
$dates = getDateRange('2024-01-01', '2024-01-10');
// ['2024-01-01', '2024-01-02', ..., '2024-01-10']

$datesThai = getDateRange('2024-01-01', '2024-01-10', 'd/m/Y');
// ['01/01/2024', '02/01/2024', ...]

วิธีเดิม: strtotime + Loop (Legacy)

function getDateRangeLegacy($date1, $date2, $format = 'd-m-Y') {
    $dates = [];
    $current = strtotime($date1);
    $end = strtotime($date2);
    $step = '+1 day';
    
    while ($current <= $end) {
        $dates[] = date($format, $current);
        $current = strtotime($step, $current);
    }
    
    return $dates;
}

ตัวอย่างการใช้งานขั้นสูง

1. ข้ามวันหยุดสุดสัปดาห์ (Business Days)

function getBusinessDays(string $startDate, string $endDate): array {
    $dates = [];
    $period = new DatePeriod(
        new DateTime($startDate),
        new DateInterval('P1D'),
        (new DateTime($endDate))->modify('+1 day')
    );
    
    foreach ($period as $date) {
        $dayOfWeek = (int)$date->format('N'); // 1=Mon, 7=Sun
        if ($dayOfWeek < 6) { // Mon-Fri
            $dates[] = $date->format('Y-m-d');
        }
    }
    
    return $dates;
}

2. เฉพาะวันเฉพาะ (เช่น ทุกวันจันทร์)

function getSpecificWeekdays(string $startDate, string $endDate, array $weekdays): array {
    // $weekdays = [1, 5] = Monday & Friday
    $dates = [];
    $period = new DatePeriod(
        new DateTime($startDate),
        new DateInterval('P1D'),
        (new DateTime($endDate))->modify('+1 day')
    );
    
    foreach ($period as $date) {
        if (in_array((int)$date->format('N'), $weekdays)) {
            $dates[] = $date->format('Y-m-d');
        }
    }
    
    return $dates;
}

3. Generator สำหรับ Memory Efficiency (Date Range ใหญ่)

function dateRangeGenerator(string $startDate, string $endDate): Generator {
    $start = new DateTime($startDate);
    $end = (new DateTime($endDate))->modify('+1 day');
    $interval = new DateInterval('P1D');
    
    for ($date = $start; $date < $end; $date->add($interval)) {
        yield $date->format('Y-m-d');
    }
}

// ใช้งาน: ไม่โหลดทั้ง Array เข้า Memory
foreach (dateRangeGenerator('2020-01-01', '2020-12-31') as $date) {
    // Process each date...
    // Memory คงที่ ไม่ขึ้นกับจำนวนวัน
}

Output Example

$dates = getDateRange('2019-11-10', '2019-11-20');
print_r($dates);
/*
Array
(
    [0] => 2019-11-10
    [1] => 2019-11-11
    [2] => 2019-11-12
    [3] => 2019-11-13
    [4] => 2019-11-14
    [5] => 2019-11-15
    [6] => 2019-11-16
    [7] => 2019-11-17
    [8] => 2019-11-18
    [9] => 2019-11-19
    [10] => 2019-11-20
)
*/

⚠️ ข้อควรระวัง

  • Timezone: DateTime ใช้ Default Timezone ตั้งค่า date_default_timezone_set('Asia/Bangkok') ก่อนใช้
  • DST: DateInterval('P1D') จัดการ DST อัตโนมัติ (ไม่ใช่ +86400 seconds)
  • Performance: สำหรับช่วงกว่า 1 ปี ควรใช้ Generator
  • Inclusive/Exclusive: ตัวอย่างข้างต้น Inclusive ทั้งสองข้าง (Modify End +1 Day)