首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 取得指定日期所在月份的第一天與最後一天 (含時間) 實用函數

     編輯:PHP 相關知識

常見需求:報表查詢、帳單週期、排程任務需確定「某月的起始 00:00:00」與「結束 23:59:59」。本文提供可直接複製的工具函數,支援任意日期字串輸入。

核心函數

<?php
/**
 * 取得指定日期所在月份的起始或結束日期時間
 *
 * @param string $date  日期字串,支援 strtotime() 所有格式 (如 '2023-05-15', 'next month', '-1 month')
 * @param bool   $first true 回傳月初 00:00:00,false 回傳月末 23:59:59
 * @return string 格式化日期時間字串 'Y-m-d H:i:s'
 */
function getMonthRange($date, $first = true) {
    $timestamp = strtotime($date);
    if ($timestamp === false) {
        throw new InvalidArgumentException("無效日期格式: $date");
    }

    if ($first) {
        // 月初第一天 00:00:00
        return date('Y-m-01 00:00:00', $timestamp);
    } else {
        // 月末最後一天 23:59:59
        // date('t') 取得該月總天數
        $lastDay = date('t', $timestamp);
        return date("Y-m-{$lastDay} 23:59:59", $timestamp);
    }
}

// 別名函數,語意更清晰
function getMonthStart($date) { return getMonthRange($date, true); }
function getMonthEnd($date)   { return getMonthRange($date, false); }
?>

使用範例

<?php
// 當前月
echo "本月開始: " . getMonthStart('now') . "\n";   // 2023-10-01 00:00:00
echo "本月結束: " . getMonthEnd('now') . "\n";     // 2023-10-31 23:59:59

// 指定日期
echo "2023-02-15 所在月開始: " . getMonthStart('2023-02-15') . "\n"; // 2023-02-01 00:00:00
echo "2023-02-15 所在月結束: " . getMonthEnd('2023-02-15') . "\n";   // 2023-02-28 23:59:59 (平年)

// 相對日期
echo "上個月開始: " . getMonthStart('-1 month') . "\n";
echo "下個月結束: " . getMonthEnd('+1 month') . "\n";

// 直接用於 SQL 查詢
$start = getMonthStart('2023-06-10');
$end   = getMonthEnd('2023-06-10');
$sql = "SELECT * FROM orders WHERE created_at BETWEEN '$start' AND '$end'";
// 結果: WHERE created_at BETWEEN '2023-06-01 00:00:00' AND '2023-06-30 23:59:59'
?>

進階:回傳 DateTime 物件 (現代寫法)

<?php
function getMonthRangeDateTime($date, $first = true) {
    $dt = new DateTime($date);
    if ($first) {
        $dt->modify('first day of this month')->setTime(0, 0, 0);
    } else {
        $dt->modify('last day of this month')->setTime(23, 59, 59);
    }
    return $dt; // 回傳 DateTime 物件,可直接 format、diff、比較
}

// 使用
$start = getMonthRangeDateTime('2023-02-15', true);
$end   = getMonthRangeDateTime('2023-02-15', false);
echo $start->format('Y-m-d H:i:s') . "\n"; // 2023-02-01 00:00:00
echo $end->format('Y-m-d H:i:s') . "\n";   // 2023-02-28 23:59:59

// 直接比較
if ($someDate >= $start && $someDate <= $end) { /* 在本月內 */ }
?>

效能與邊界測試

輸入月初輸出月末輸出說明
2024-02-29 (閏年)2024-02-01 00:00:002024-02-29 23:59:59正確處理 2 月 29 天
2023-02-28 (平年)2023-02-01 00:00:002023-02-28 23:59:59正確處理 2 月 28 天
2023-12-312023-12-01 00:00:002023-12-31 23:59:59跨年無問題
first day of January 20002000-01-01 00:00:002000-01-31 23:59:59支援文字描述

常見陷阱

  • date('Y-m-d', strtotime('last day of')) 在某些舊 PHP 版本不支援,建議用 date('t') 取得天數最穩健。
  • 資料庫 BETWEEN 包含邊界,若欄位為 DATETIME 精度到秒,23:59:59 正確;若為 TIMESTAMP 或更高精度,建議用 < '2023-03-01 00:00:00' 開區間寫法。
  • 時區影響:strtotime 使用預設時區 (date_default_timezone_set),跨時區應用建議統一用 UTC 存儲,顯示時轉換。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved