PHP之常用日期处理类

在PHP中我们要经常处理一些时间操作,我总结了一下常用的日期处理方法,仅供参考.

<?php

namespace fast;

use DateTime;
use DateTimeZone;

/**
 * 日期时间处理类
 */
class Date
{
    const YEAR = 31536000;
    const MONTH = 2592000;
    const WEEK = 604800;
    const DAY = 86400;
    const HOUR = 3600;
    const MINUTE = 60;
    
    /**
     * 计算当前月的开始日期,结束日期
     * @param string $date 日期 2021-07
     * @param bool $timestamp  返回格式 是否为时间戳
     * @return  array
     */
    public static function getMonthStartAndEnd($date,$timestamp)
    {
       $firstDay = date('Y-m-01', strtotime($date));
       $lastDay = date('Y-m-d', strtotime("$firstDay +1 month -1 day"));
       if($timestamp){
           return array(strtotime($firstDay), strtotime($lastDay));
       }else{
           return array($firstDay, $lastDay);
       }
    }

    /**
     * 计算当前月的开始日期
     * @param string $date 日期 2021-07-01
     * @param bool $timestamp  返回格式 是否为时间戳
     * @return  string
     */
    public static function getMonthStart($date,$timestamp)
    {
        $firstDay = date('Y-m-01', strtotime($date));
        if($timestamp){
            return strtotime($firstDay);
        }else{
            return $firstDay.' 00:00:00';
        }
    }

    /**
     * 计算当前月的结束日期
     * @param string $date 日期 2021-07-31
     * @param bool $timestamp  返回格式 是否为时间戳
     * @return  string
     */
    public static function getMonthEnd($date,$timestamp)
    {
        $firstDay = date('Y-m-01', strtotime($date));
        $lastDay = date('Y-m-d', strtotime("$firstDay +1 month -1 day"));
        if($timestamp){
            return strtotime($lastDay) + 24 * 60* 60 -1;
        }else{
            return $lastDay . ' 23:59:59';
        }
    }

    /**
     * 计算上个月的年月
     * @return  string
     */
    public static function previousDate(){
        // 本月第一天
        $firstDate = date("Y-m-01", time());
        return date('Y-m',strtotime('-1 day', strtotime($firstDate)));
    }

    /**
     * 计算两个时区间相差的时长,单位为秒
     *
     * $seconds = self::offset('America/Chicago', 'GMT');
     *
     * [!!] A list of time zones that PHP supports can be found at
     * <http://php.net/timezones>.
     *
     * @param string $remote timezone that to find the offset of
     * @param string $local  timezone used as the baseline
     * @param mixed  $now    UNIX timestamp or date string
     * @return  integer
     */
    public static function offset($remote, $local = null, $now = null)
    {
        if ($local === null) {
            // Use the default timezone
            $local = date_default_timezone_get();
        }
        if (is_int($now)) {
            // Convert the timestamp into a string
            $now = date(DateTime::RFC2822, $now);
        }
        // Create timezone objects
        $zone_remote = new DateTimeZone($remote);
        $zone_local = new DateTimeZone($local);
        // Create date objects from timezones
        $time_remote = new DateTime($now, $zone_remote);
        $time_local = new DateTime($now, $zone_local);
        // Find the offset
        $offset = $zone_remote->getOffset($time_remote) - $zone_local->getOffset($time_local);
        return $offset;
    }

    /**
     * 计算两个时间戳之间相差的时间
     *
     * $span = self::span(60, 182, 'minutes,seconds'); // array('minutes' => 2, 'seconds' => 2)
     * $span = self::span(60, 182, 'minutes'); // 2
     *
     * @param int    $remote timestamp to find the span of
     * @param int    $local  timestamp to use as the baseline
     * @param string $output formatting string
     * @return  string   when only a single output is requested
     * @return  array    associative list of all outputs requested
     * @from https://github.com/kohana/ohanzee-helpers/blob/master/src/Date.php
     */
    public static function span($remote, $local = null, $output = 'years,months,weeks,days,hours,minutes,seconds')
    {
        // Normalize output
        $output = trim(strtolower((string)$output));
        if (!$output) {
            // Invalid output
            return false;
        }
        // Array with the output formats
        $output = preg_split('/[^a-z]+/', $output);
        // Convert the list of outputs to an associative array
        $output = array_combine($output, array_fill(0, count($output), 0));
        // Make the output values into keys
        extract(array_flip($output), EXTR_SKIP);
        if ($local === null) {
            // Calculate the span from the current time
            $local = time();
        }
        // Calculate timespan (seconds)
        $timespan = abs($remote - $local);
        if (isset($output['years'])) {
            $timespan -= self::YEAR * ($output['years'] = (int)floor($timespan / self::YEAR));
        }
        if (isset($output['months'])) {
            $timespan -= self::MONTH * ($output['months'] = (int)floor($timespan / self::MONTH));
        }
        if (isset($output['weeks'])) {
            $timespan -= self::WEEK * ($output['weeks'] = (int)floor($timespan / self::WEEK));
        }
        if (isset($output['days'])) {
            $timespan -= self::DAY * ($output['days'] = (int)floor($timespan / self::DAY));
        }
        if (isset($output['hours'])) {
            $timespan -= self::HOUR * ($output['hours'] = (int)floor($timespan / self::HOUR));
        }
        if (isset($output['minutes'])) {
            $timespan -= self::MINUTE * ($output['minutes'] = (int)floor($timespan / self::MINUTE));
        }
        // Seconds ago, 1
        if (isset($output['seconds'])) {
            $output['seconds'] = $timespan;
        }
        if (count($output) === 1) {
            // Only a single output was requested, return it
            return array_pop($output);
        }
        // Return array
        return $output;
    }
    
    /**
         * 格式化 时间格式
         *
         * @param string $time 本地时间
         * @return    string    格式化的日期字符串
         */
        public static  function ReckonTime($time)
            {
                $NowTime = time();
                if($time > $NowTime){ return false; }
                $TimePoor = $NowTime - $time;
                if ($TimePoor == 0) {
                    $str = '一眨眼之间';
                } else if ($TimePoor < 60 && $TimePoor > 0) {
                    $str = $TimePoor . '秒之前';
                } else if ($TimePoor >= 60 && $TimePoor <= 60 * 60) {
                    $str = floor($TimePoor / 60) . '分钟前';
                } else if ($TimePoor > 60 * 60 && $TimePoor <= 3600 * 24) {
                    $str = floor($TimePoor / 3600) . '小时前';
                } else if ($TimePoor > 3600 * 24 && $TimePoor <= 3600 * 24 * 7) {
                    if (floor($TimePoor / (3600 * 24)) == 1) {
                        $str = "昨天";
                    } else if (floor($TimePoor / (3600 * 24)) == 2) {
                        $str = "前天";
                    } else {
                        $str = floor($TimePoor / (3600 * 24)) . '天前';
                    }
                } else if ($TimePoor > 3600 * 24 * 7) {
                    $str = date("Y-m-d", $time);
                }
                return $str;
            }

    /**
     * 格式化 UNIX 时间戳为人易读的字符串
     *
     * @param int    Unix 时间戳
     * @param mixed $local 本地时间
     *
     * @return    string    格式化的日期字符串
     */
    public static function human($remote, $local = null)
    {
        $time_diff = (is_null($local) || $local ? time() : $local) - $remote;
        $tense = $time_diff < 0 ? 'after' : 'ago';
        $time_diff = abs($time_diff);
        $chunks = [
            [60 * 60 * 24 * 365, 'year'],
            [60 * 60 * 24 * 30, 'month'],
            [60 * 60 * 24 * 7, 'week'],
            [60 * 60 * 24, 'day'],
            [60 * 60, 'hour'],
            [60, 'minute'],
            [1, 'second']
        ];
        $name = 'second';
        $count = 0;

        for ($i = 0, $j = count($chunks); $i < $j; $i++) {
            $seconds = $chunks[$i][0];
            $name = $chunks[$i][1];
            if (($count = floor($time_diff / $seconds)) != 0) {
                break;
            }
        }
        return __("%d $name%s $tense", $count, ($count > 1 ? 's' : ''));
    }

    /**
     * 获取一个基于时间偏移的Unix时间戳
     *
     * @param string $type     时间类型,默认为day,可选minute,hour,day,week,month,quarter,year
     * @param int    $offset   时间偏移量 默认为0,正数表示当前type之后,负数表示当前type之前
     * @param string $position 时间的开始或结束,默认为begin,可选前(begin,start,first,front),end
     * @param int    $year     基准年,默认为null,即以当前年为基准
     * @param int    $month    基准月,默认为null,即以当前月为基准
     * @param int    $day      基准天,默认为null,即以当前天为基准
     * @param int    $hour     基准小时,默认为null,即以当前年小时基准
     * @param int    $minute   基准分钟,默认为null,即以当前分钟为基准
     * @return int 处理后的Unix时间戳
     */
    public static function unixtime($type = 'day', $offset = 0, $position = 'begin', $year = null, $month = null, $day = null, $hour = null, $minute = null)
    {
        $year = is_null($year) ? date('Y') : $year;
        $month = is_null($month) ? date('m') : $month;
        $day = is_null($day) ? date('d') : $day;
        $hour = is_null($hour) ? date('H') : $hour;
        $minute = is_null($minute) ? date('i') : $minute;
        $position = in_array($position, array('begin', 'start', 'first', 'front'));

        $baseTime = mktime(0, 0, 0, $month, $day, $year);

        switch ($type) {
            case 'minute':
                $time = $position ? mktime($hour, $minute + $offset, 0, $month, $day, $year) : mktime($hour, $minute + $offset, 59, $month, $day, $year);
                break;
            case 'hour':
                $time = $position ? mktime($hour + $offset, 0, 0, $month, $day, $year) : mktime($hour + $offset, 59, 59, $month, $day, $year);
                break;
            case 'day':
                $time = $position ? mktime(0, 0, 0, $month, $day + $offset, $year) : mktime(23, 59, 59, $month, $day + $offset, $year);
                break;
            case 'week':
                $weekIndex = date("w", $baseTime);
                $time = $position ?
                    strtotime($offset . " weeks", strtotime(date('Y-m-d', strtotime("-" . ($weekIndex ? $weekIndex - 1 : 6) . " days", $baseTime)))) :
                    strtotime($offset . " weeks", strtotime(date('Y-m-d 23:59:59', strtotime("+" . (6 - ($weekIndex ? $weekIndex - 1 : 6)) . " days", $baseTime))));
                break;
            case 'month':
                $_timestamp = mktime(0, 0, 0, $month + $offset, 1, $year);
                $time = $position ? $_timestamp : mktime(23, 59, 59, $month + $offset, cal_days_in_month(CAL_GREGORIAN, date("m", $_timestamp), date("Y", $_timestamp)), $year);
                break;
            case 'quarter':
                $_month = date("m", mktime(0, 0, 0, (ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) * 3, $day, $year));
                $time = $position ?
                    mktime(0, 0, 0, 1 + ((ceil(date('n', $baseTime) / 3) + $offset) - 1) * 3, 1, $year) :
                    mktime(23, 59, 59, (ceil(date('n', $baseTime) / 3) + $offset) * 3, cal_days_in_month(CAL_GREGORIAN, (ceil(date('n', $baseTime) / 3) + $offset) * 3, $year), $year);
                break;
            case 'year':
                $time = $position ? mktime(0, 0, 0, 1, 1, $year + $offset) : mktime(23, 59, 59, 12, 31, $year + $offset);
                break;
            default:
                $time = mktime($hour, $minute, 0, $month, $day, $year);
                break;
        }
        return $time;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swoole~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值