本文目录导读:

我来为你创建一个功能完善的PHP日期时间工具库:
日期时间工具类 DateTimeHelper
<?php
/**
* DateTimeHelper - 日期时间工具类
*
* @author Your Name
* @version 1.0.0
*/
class DateTimeHelper
{
/** @var string 默认时区 */
private static $defaultTimezone = 'Asia/Shanghai';
/** @var string 默认日期格式 */
private static $defaultFormat = 'Y-m-d H:i:s';
/** @var array 中文星期 */
private static $weekChinese = ['日', '一', '二', '三', '四', '五', '六'];
/** @var array 中文月份 */
private static $monthChinese = [
1 => '一月', 2 => '二月', 3 => '三月', 4 => '四月',
5 => '五月', 6 => '六月', 7 => '七月', 8 => '八月',
9 => '九月', 10 => '十月', 11 => '十一月', 12 => '十二月'
];
// ==================== 初始化与配置 ====================
/**
* 设置默认时区
* @param string $timezone
*/
public static function setDefaultTimezone($timezone)
{
self::$defaultTimezone = $timezone;
date_default_timezone_set($timezone);
}
/**
* 设置默认日期格式
* @param string $format
*/
public static function setDefaultFormat($format)
{
self::$defaultFormat = $format;
}
// ==================== 格式化输出 ====================
/**
* 格式化当前时间
* @param string $format 格式
* @return string
*/
public static function now($format = null)
{
$format = $format ?: self::$defaultFormat;
return date($format);
}
/**
* 格式化时间戳为指定格式
* @param int|string $timestamp 时间戳或日期字符串
* @param string $format 格式
* @return string
*/
public static function format($timestamp, $format = null)
{
$format = $format ?: self::$defaultFormat;
$timestamp = self::toTimestamp($timestamp);
return date($format, $timestamp);
}
/**
* 人性化时间显示(相对时间)
* @param int|string $time 时间戳或日期字符串
* @return string
*/
public static function humanize($time)
{
$timestamp = self::toTimestamp($time);
$diff = time() - $timestamp;
if ($diff < 0) {
// 未来时间
$diff = abs($diff);
$suffix = '后';
} else {
$suffix = '前';
}
if ($diff < 60) {
return "刚刚";
} elseif ($diff < 3600) {
return floor($diff / 60) . "分钟" . $suffix;
} elseif ($diff < 86400) {
return floor($diff / 3600) . "小时" . $suffix;
} elseif ($diff < 2592000) {
return floor($diff / 86400) . "天" . $suffix;
} elseif ($diff < 31536000) {
return floor($diff / 2592000) . "个月" . $suffix;
} else {
return floor($diff / 31536000) . "年" . $suffix;
}
}
/**
* 中文日期格式
* @param int|string $time 时间戳或日期字符串
* @return string 如:2024年1月15日 星期一
*/
public static function chineseFormat($time = null)
{
$timestamp = $time ? self::toTimestamp($time) : time();
$year = date('Y', $timestamp);
$month = (int)date('n', $timestamp);
$day = (int)date('j', $timestamp);
$week = date('w', $timestamp);
return "{$year}年{$month}月{$day}日 星期" . self::$weekChinese[$week];
}
// ==================== 解析与转换 ====================
/**
* 将日期字符串或时间戳统一转为时间戳
* @param int|string $datetime
* @return int
*/
public static function toTimestamp($datetime)
{
if (is_numeric($datetime)) {
return (int)$datetime;
}
if (strtotime($datetime) === false) {
throw new InvalidArgumentException("无效的日期时间: {$datetime}");
}
return strtotime($datetime);
}
/**
* 将日期字符串转为DateTime对象
* @param int|string $datetime
* @return \DateTime
*/
public static function toDateTime($datetime = 'now')
{
if ($datetime instanceof \DateTime) {
return $datetime;
}
if (is_numeric($datetime)) {
return (new \DateTime())->setTimestamp($datetime);
}
return new \DateTime($datetime, new \DateTimeZone(self::$defaultTimezone));
}
/**
* 解析ISO 8601格式(用于JSON等)
* @param string $isoString
* @return int 时间戳
*/
public static function fromISO8601($isoString)
{
$date = \DateTime::createFromFormat(\DateTime::ATOM, $isoString);
return $date ? $date->getTimestamp() : null;
}
/**
* 输出ISO 8601格式
* @param int|string $time
* @return string
*/
public static function toISO8601($time = null)
{
$timestamp = $time ? self::toTimestamp($time) : time();
return date('c', $timestamp);
}
// ==================== 计算与差值 ====================
/**
* 计算两个日期之间的差值
* @param int|string $start 开始日期
* @param int|string $end 结束日期
* @param string $unit 单位:years|months|days|hours|minutes|seconds
* @return float|int
*/
public static function diff($start, $end, $unit = 'days')
{
$startTs = self::toTimestamp($start);
$endTs = self::toTimestamp($end);
$diff = abs($endTs - $startTs);
switch ($unit) {
case 'years':
return floor($diff / 31536000);
case 'months':
return floor($diff / 2592000);
case 'days':
return floor($diff / 86400);
case 'hours':
return floor($diff / 3600);
case 'minutes':
return floor($diff / 60);
case 'seconds':
return $diff;
default:
return $diff;
}
}
/**
* 添加时间
* @param int|string $datetime 原始时间
* @param int $amount 数量
* @param string $unit 单位:years|months|days|hours|minutes|seconds
* @return string 格式化后的时间
*/
public static function add($datetime, $amount, $unit = 'days')
{
$date = self::toDateTime($datetime);
$date->modify("+{$amount} {$unit}");
return $date->format(self::$defaultFormat);
}
/**
* 减去时间
* @param int|string $datetime 原始时间
* @param int $amount 数量
* @param string $unit 单位:years|months|days|hours|minutes|seconds
* @return string 格式化后的时间
*/
public static function subtract($datetime, $amount, $unit = 'days')
{
$date = self::toDateTime($datetime);
$date->modify("-{$amount} {$unit}");
return $date->format(self::$defaultFormat);
}
/**
* 计算年龄
* @param string $birthday 出生日期
* @return int 年龄
*/
public static function age($birthday)
{
$birthDate = self::toDateTime($birthday);
$now = new \DateTime();
return $birthDate->diff($now)->y;
}
// ==================== 区间与范围 ====================
/**
* 获取日期所处的季度
* @param int|string $time
* @return int 1-4
*/
public static function getQuarter($time = null)
{
$timestamp = $time ? self::toTimestamp($time) : time();
$month = (int)date('n', $timestamp);
return (int)ceil($month / 3);
}
/**
* 获取某年月的天数
* @param int $year 年份
* @param int $month 月份
* @return int 天数
*/
public static function daysInMonth($year, $month)
{
return cal_days_in_month(CAL_GREGORIAN, $month, $year);
}
/**
* 获取某周的第一天和最后一天
* @param int|string $time
* @return array ['start' => 周一日期, 'end' => 周日日期]
*/
public static function weekRange($time = null)
{
$timestamp = $time ? self::toTimestamp($time) : time();
$dayOfWeek = (int)date('w', $timestamp);
// 周一到周日为一周
if ($dayOfWeek == 0) {
$dayOfWeek = 7;
}
$start = strtotime('-' . ($dayOfWeek - 1) . ' days', $timestamp);
$end = strtotime('+' . (7 - $dayOfWeek) . ' days', $timestamp);
return [
'start' => date('Y-m-d', $start) . ' 00:00:00',
'end' => date('Y-m-d', $end) . ' 23:59:59'
];
}
/**
* 获取某月的第一天和最后一天
* @param int|string $time
* @return array ['start' => 月初, 'end' => 月末]
*/
public static function monthRange($time = null)
{
$timestamp = $time ? self::toTimestamp($time) : time();
$firstDay = date('Y-m-01', $timestamp);
$lastDay = date('Y-m-t', $timestamp);
return [
'start' => $firstDay . ' 00:00:00',
'end' => $lastDay . ' 23:59:59'
];
}
// ==================== 检查与验证 ====================
/**
* 检查是否为闰年
* @param int $year
* @return bool
*/
public static function isLeapYear($year)
{
return ($year % 4 == 0 && $year % 100 != 0) || ($year % 400 == 0);
}
/**
* 验证日期字符串是否有效
* @param string $date
* @param string $format 期望格式,如 Y-m-d
* @return bool
*/
public static function isValid($date, $format = 'Y-m-d')
{
$d = \DateTime::createFromFormat($format, $date);
return $d && $d->format($format) === $date;
}
/**
* 检查日期是否为今天的日期
* @param int|string $time
* @return bool
*/
public static function isToday($time)
{
$timestamp = self::toTimestamp($time);
return date('Y-m-d', $timestamp) === date('Y-m-d');
}
/**
* 检查日期是否在指定范围内
* @param int|string $time 要检查的日期
* @param int|string $start 开始日期
* @param int|string $end 结束日期
* @return bool
*/
public static function isBetween($time, $start, $end)
{
$timeTs = self::toTimestamp($time);
$startTs = self::toTimestamp($start);
$endTs = self::toTimestamp($end);
return $timeTs >= $startTs && $timeTs <= $endTs;
}
// ==================== 特殊功能 ====================
/**
* 获取东方星座日期字符串
* @param int|string $time
* @return string
*/
public static function zodiac($time = null)
{
$timestamp = $time ? self::toTimestamp($time) : time();
$year = (int)date('Y', $timestamp);
// 简化示例 - 仅根据年份返回生肖
$zodiac = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
$startYear = 1900; // 鼠年起始
return $zodiac[($year - $startYear) % 12];
}
/**
* 获取西方星座
* @param int|string $time
* @return string
*/
public static function westernZodiac($time = null)
{
$timestamp = $time ? self::toTimestamp($time) : time();
$month = (int)date('n', $timestamp);
$day = (int)date('j', $timestamp);
$signs = [
['21', '水瓶座'], ['20', '双鱼座'], ['21', '白羊座'],
['21', '金牛座'], ['22', '双子座'], ['22', '巨蟹座'],
['23', '狮子座'], ['23', '处女座'], ['24', '天秤座'],
['24', '天蝎座'], ['23', '射手座'], ['22', '摩羯座']
];
$index = $month - 1;
if ($day < (int)$signs[$index][0]) {
$index = ($index - 1 + 12) % 12;
}
return $signs[$index][1];
}
/**
* 获取中国的节气(简化版)
* @param int $year
* @param int $month
* @return array 当月节气列表
*/
public static function solarTerms($year, $month)
{
// 简化示例 - 实际需要查表
$terms = [
1 => '小寒,大寒', 2 => '立春,雨水',
3 => '惊蛰,春分', 4 => '清明,谷雨',
5 => '立夏,小满', 6 => '芒种,夏至',
7 => '小暑,大暑', 8 => '立秋,处暑',
9 => '白露,秋分', 10 => '寒露,霜降',
11 => '立冬,小雪', 12 => '大雪,冬至'
];
return explode(',', $terms[$month]);
}
/**
* 获取自然周、月、年的起始时间(用于报表)
* @param string $period 周期类型:today|yesterday|week|month|quarter|year
* @return array ['start' => 开始时间, 'end' => 结束时间]
*/
public static function getPeriod($period)
{
switch ($period) {
case 'today':
return [
'start' => date('Y-m-d') . ' 00:00:00',
'end' => date('Y-m-d') . ' 23:59:59'
];
case 'yesterday':
$yesterday = date('Y-m-d', strtotime('-1 day'));
return [
'start' => $yesterday . ' 00:00:00',
'end' => $yesterday . ' 23:59:59'
];
case 'week':
$range = self::weekRange();
return $range;
case 'month':
return self::monthRange();
case 'quarter':
$quarter = self::getQuarter();
$startMonth = ($quarter - 1) * 3 + 1;
$start = date('Y') . '-' . $startMonth . '-01';
$endMonth = $startMonth + 2;
$end = date('Y') . '-' . $endMonth . '-' . date('t', strtotime($start . ' +2 months'));
return [
'start' => $start . ' 00:00:00',
'end' => $end . ' 23:59:59'
];
case 'year':
return [
'start' => date('Y') . '-01-01 00:00:00',
'end' => date('Y') . '-12-31 23:59:59'
];
default:
return null;
}
}
/**
* 获取两个日期之间的所有日期
* @param string $startDate 开始日期(Y-m-d)
* @param string $endDate 结束日期(Y-m-d)
* @return array 日期数组
*/
public static function getDateRange($startDate, $endDate)
{
$dates = [];
$startTs = strtotime($startDate);
$endTs = strtotime($endDate);
for ($ts = $startTs; $ts <= $endTs; $ts += 86400) {
$dates[] = date('Y-m-d', $ts);
}
return $dates;
}
}
使用示例
<?php
// 设置默认时区
DateTimeHelper::setDefaultTimezone('Asia/Shanghai');
// 基本格式化
echo DateTimeHelper::now(); // 2024-01-15 14:30:45
echo DateTimeHelper::now('Y年m月d日 H:i'); // 2024年01月15日 14:30
// 时间戳转换
echo DateTimeHelper::toISO8601('2024-01-15 14:30:00');
echo DateTimeHelper::fromISO8601('2024-01-15T14:30:00+08:00');
// 相对时间
echo DateTimeHelper::humanize(strtotime('-1 hour')); // 1小时前
echo DateTimeHelper::humanize(strtotime('+2 days')); // 2天后
// 中文字符串
echo DateTimeHelper::chineseFormat('2024-01-15'); // 2024年1月15日 星期一
// 日期计算
echo DateTimeHelper::diff('2024-01-01', '2024-12-31', 'days'); // 365
echo DateTimeHelper::add('2024-01-01', 30, 'days'); // 2024-01-31
echo DateTimeHelper::subtract('2024-01-01', 1, 'months'); // 2023-12-01
// 年龄计算
echo DateTimeHelper::age('1990-01-01'); // 34
// 验证
var_dump(DateTimeHelper::isValid('2024-02-30')); // false
var_dump(DateTimeHelper::isLeapYear(2024)); // true
// 范围查询
print_r(DateTimeHelper::weekRange('2024-01-15'));
print_r(DateTimeHelper::monthRange('2024-02-15'));
// 星座
echo DateTimeHelper::zodiac('2024-01-01'); // 龙
echo DateTimeHelper::westernZodiac('2024-08-15'); // 狮子座
// 获取报表周期
print_r(DateTimeHelper::getPeriod('week'));
print_r(DateTimeHelper::getPeriod('quarter'));
// 日期序列
$dates = DateTimeHelper::getDateRange('2024-01-01', '2024-01-07');
print_r($dates);
扩展建议
- 连接数据库时自动调用
setDefaultTimezone()确保时区一致 - 在框架初始化时设置默认格式
- 根据业务需求扩展更多功能(如农历转换、时区换算等)
- 对于高性能场景,考虑用
Carbon或Chronos等第三方库
这个工具类涵盖了开发中常用的日期时间处理需求,可以根据实际项目进一步定制。