Datefmt 日期格式化工具類
<?php
class Datefmt {
public function __construct() {}
/** 根據日期獲取所在週的起止時間 */
public function get_weekinfo_by_date($date) {
$idx = strftime("%u", strtotime($date)); // 1=週一 ... 7=週日
$mon_idx = $idx - 1;
$sun_idx = $idx - 7;
return [
'week_start_day' => strftime('%Y-%m-%d', strtotime($date) - $mon_idx * 86400),
'week_end_day' => strftime('%Y-%m-%d', strtotime($date) - $sun_idx * 86400),
];
}
/** 根據日期獲取所在月的起止時間 */
public function get_monthinfo_by_date($date) {
$timestamp = strtotime($date);
$mdays = date('t', $timestamp); // 當月總天數
return [
'month_start_day' => date('Y-m-1', $timestamp),
'month_end_day' => date('Y-m-' . $mdays, $timestamp),
];
}
/** 獲取區間內所有週 */
public function get_weeks($sdate, $edate) {
$range_arr = [];
$this->check_date([$sdate, $edate]);
do {
$weekinfo = $this->get_weekinfo_by_date($sdate);
$end_day = $weekinfo['week_end_day'];
$start = $this->substr_date($weekinfo['week_start_day']);
$end = $this->substr_date($weekinfo['week_end_day']);
$range_arr[] = "{$start} ~ {$end}";
$sdate = date('Y-m-d', strtotime($sdate) + 7 * 86400);
} while ($end_day < $edate);
return $range_arr;
}
/** 獲取區間內所有月 */
public function get_months($sdate, $edate) {
$range_arr = [];
do {
$monthinfo = $this->get_monthinfo_by_date($sdate);
$end_day = $monthinfo['month_end_day'];
$start = $this->substr_date($monthinfo['month_start_day']);
$end = $this->substr_date($monthinfo['month_end_day']);
$range_arr[] = "{$start} ~ {$end}";
$sdate = date('Y-m-d', strtotime($sdate . ' +1 month'));
} while ($end_day < $edate);
return $range_arr;
}
/** 截取月-日格式 */
private function substr_date($date) {
if (!$date) return false;
return date('m-d', strtotime($date));
}
/** 驗證日期格式 YYYY-mm-dd */
private function check_date($date_arr) {
$invalid = [];
foreach ($date_arr as $row) {
$ts = strtotime($row);
$std = date('Y-m-d', $ts);
if ($std !== $row) $invalid[] = $row;
}
if ($invalid) die("invalid date -> " . print_r($invalid, true));
}
}
使用範例與輸出
<?php
require_once "Datefmt.class.php";
$datefmt = new Datefmt();
// 11月5日到29日之間的週
var_dump($datefmt->get_weeks('2014-11-05', '2014-11-29'));
/* 輸出:
array(4) {
[0]=> string(13) "11-03 ~ 11-09"
[1]=> string(13) "11-10 ~ 11-16"
[2]=> string(13) "11-17 ~ 11-23"
[3]=> string(13) "11-24 ~ 11-30"
}
*/
// 2月3日到11月29日之間的月
var_dump($datefmt->get_months('2014-02-03', '2014-11-29'));
/* 輸出:10個月份區間,從 02-01 ~ 02-28 到 11-01 ~ 11-30 */
應用場景
- 報表系統:按週/月自動生成統計區間
- 行事曆組件:前端顯示週/月視圖範圍
- 財務結算:自動計算會計期間起止日
現代化改造建議
- 改用
DateTime / DateTimeImmutable 物件導向 API
- 支援時區設定
DateTimeZone
- 引入
Carbon 或 Chronos 函式庫簡化操作