PHP 日期时间工具库

wen PHP项目 3

本文目录导读:

PHP 日期时间工具库

  1. 日期时间工具类 DateTimeHelper
  2. 使用示例
  3. 扩展建议

我来为你创建一个功能完善的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);

扩展建议

  1. 连接数据库时自动调用 setDefaultTimezone() 确保时区一致
  2. 在框架初始化时设置默认格式
  3. 根据业务需求扩展更多功能(如农历转换、时区换算等)
  4. 对于高性能场景,考虑用 CarbonChronos 等第三方库

这个工具类涵盖了开发中常用的日期时间处理需求,可以根据实际项目进一步定制。

抱歉,评论功能暂时关闭!