<?php use DateTime; /** * 时间助手类 */ class Time { /** * 判断是否为时间戳格式 * @param int|string $timestamp 要判断的字符串 * @return bool 如果是时间戳返回True,否则返回False */ public static function is_timestamp($timestamp): bool { if (!is_int($timestamp)) { return false; } if (strtotime(date('Y-m-d H:i:s', $timestamp)) === $timestamp) { return true; } else { return false; } } /** * 将任意时间类型的参数转为时间戳 * 请注意 m/d/y 或 d-m-y 格式的日期,如果分隔符是斜线(/),则使用美洲的 m/d/y 格式。如果分隔符是横杠(-)或者点(.),则使用欧洲的 d-m-y 格式。为了避免潜在的错误,您应该尽可能使用 YYYY-MM-DD 格式或者使用 date_create_from_format() 函数。 * @param int|string $datetime 要转换为时间戳的字符串或数字 * @return int 时间戳 */ public static function toTimestamp($datetime): int { if (!$datetime) { throw new \InvalidArgumentException('Param datetime must be a timestamp or a string time'); } $start = strtotime('1970-01-01 07:00:00'); // 0 $end = strtotime('2038-01-19 03:14:07'); // 2147454847 //判断是否为时间戳 if (is_numeric($datetime) && $datetime <= $end && $datetime >= $start) { return intval($datetime); } else { $timestamp = strtotime($datetime); if ($timestamp) { return $timestamp; } else { throw new \InvalidArgumentException('Param datetime must be a timestamp or a string time'); } } } /** * 返回到今天晚上零点之前的秒数 * @return false|int 秒数 */ public static function secondEndToday() { list($y, $m, $d) = explode('-', date('Y-m-d')); return mktime(23, 59, 59, $m, $d, $y) - time(); } /** * 返回一天的秒数,传入参数可以返回数天的秒数 * @param int $days 天数,默认为1天 * @return float|int 秒数 */ public static function secondDay(int $days = 1) { return 86400 * $days; } /** * 返回一周的秒数,传入参数可以返回数周的秒数 * @param int $weeks 周数,默认为1周 * @return float|int 秒数 */ public static function secondWeek(int $weeks = 1) { return 604800 * $weeks; } /** * 友好的时间显示 * @param int|string $time 时间日期的字符串或数字 * @param int $max_days 转换格式的最大天数,超过此天数则直接显示日期,默认为365 * @param string $format 格式,和date函数格式一致,默认为Y年m月d日 * @param string $lang 语言,默认为中文,如果要显示英文传入en即可 * @return false|string 转换后的友好时间格式 */ public static function friendly_date($time, int $max_days = 365, string $format = 'Y年m月d日', string $lang = 'zh') { $time = self::toTimestamp($time); $now_time = time(); if ($time > $now_time) { return date($format, $time); } $z = date('z', $time); //当前的第几天 $now_days = date('z', $now_time); if ($z > $now_days) { $now_days += 365; } $diff_days = $now_days - $z; //获取差异天 $diffs = $now_time - $time; //获取差异秒 if ($diff_days >= $max_days) { return date($format, $time); } elseif ($diff_days >= 2) { return $diff_days . ($lang == 'zh' ? '天前' : ' days ago'); } elseif ($diff_days >= 1) { return $lang == 'zh' ? '昨天' : 'yesterday'; } elseif ($diffs >= 3600) { return floor($diffs / 3600) . ($lang == 'zh' ? '小时前' : ' hours ago'); } elseif ($diffs >= 60) { return floor($diffs / 60) . ($lang == 'zh' ? '分钟前' : ' minutes ago'); } elseif ($diffs >= 10) { return $diffs . ($lang == 'zh' ? '秒前' : ' seconds ago'); } else { return $lang == 'zh' ? '刚刚' : 'just'; } } /** * 判断日期是否为今天 * @param string|int $datetime 时间日期 * @return bool 如果是今天则返回True,否则返回False */ public static function isToday($datetime): bool { $timestamp = self::toTimestamp($datetime); if (date('Y-m-d', $timestamp) == date('Y-m-d')) { return true; } else { return false; } } /** * 判断日期是否为本周 * @param string|int $datetime 时间日期 * @return bool 如果是本周则返回True,否则返回False */ public static function isThisWeek($datetime): bool { $week_start = strtotime(date('Y-m-d 00:00:00', strtotime('this week'))); $week_end = strtotime(date('Y-m-d 23:59:59', strtotime('last day next week'))); $timestamp = self::toTimestamp($datetime); if ($timestamp >= $week_start && $timestamp <= $week_end) { return true; } else { return false; } } /** * 判断日期是否为本月 * @param string|int $datetime 时间日期 * @return bool 如果是本月则返回True,否则返回False */ public static function isThisMonth($datetime): bool { $timestamp = self::toTimestamp($datetime); if (date('Y-m', $timestamp) == date('Y-m')) { return true; } else { return false; } } /** * 判断日期是否为今年 * @param string|int $datetime 时间日期 * @return bool 如果是今年则返回True,否则返回False */ public static function isThisYear($datetime): bool { $timestamp = self::toTimestamp($datetime); if (date('Y', $timestamp) == date('Y')) { return true; } else { return false; } } /** * 返回两个日期相差天数(如果只传入一个日期,则与当天时间比较) * @param int|string $datetime 要计算的时间 * @param int|string $new_datetime 要比较的时间(默认为当前时间) * @return int 相差天数 */ public static function diffDays($datetime, $new_datetime = null): int { $datetime = date('Y-m-d', self::toTimestamp($datetime)); if ($new_datetime) { $new_datetime = date('Y-m-d', self::toTimestamp($new_datetime)); } else { $new_datetime = date('Y-m-d'); } return date_diff(date_create($datetime), date_create($new_datetime))->days; } /** * 返回两个日期相差星期数(如果只传入一个日期,则与当天时间比较) * @param int|string $datetime 要计算的时间 * @param int|string $new_datetime 要比较的时间(默认为当前时间) * @return int 相差星期数 */ public static function diffWeeks($datetime, $new_datetime = null): int { $datetime = date('Y-m-d', self::toTimestamp($datetime)); if ($new_datetime) { $new_datetime = date('Y-m-d', self::toTimestamp($new_datetime)); } else { $new_datetime = date('Y-m-d'); } return date_diff(date_create($datetime), date_create($new_datetime))->days / 7; } /** * 返回两个日期相差月数(如果只传入一个日期,则与当天时间比较) * @param int|string $datetime 要计算的时间 * @param int|string $new_datetime 要比较的时间(默认为当前时间) * @return int 相差月数 */ public static function diffMonth($datetime, $new_datetime = null): int { $datetime = date('Y-m-d', self::toTimestamp($datetime)); if ($new_datetime) { $new_datetime = date('Y-m-d', self::toTimestamp($new_datetime)); } else { $new_datetime = date('Y-m-d'); } $diff = date_diff(date_create($datetime), date_create($new_datetime)); return $diff->y * 12 + $diff->m; } /** * 返回两个日期相差年数(如果只传入一个日期,则与当前时间比较) * @param int|string $datetime 要计算的时间 * @param int|string $new_datetime 要比较的时间(默认为当前时间) * @return int 相差年数 */ public static function diffYears($datetime, $new_datetime = null): int { $datetime = date('Y-m-d', self::toTimestamp($datetime)); if ($new_datetime) { $new_datetime = date('Y-m-d', self::toTimestamp($new_datetime)); } else { $new_datetime = date('Y-m-d'); } return date_diff(date_create($datetime), date_create($new_datetime))->y; } /** * 返回传入时间的N分钟前的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $minute 分钟数(默认为1分钟) * @return int 时间戳 */ public static function beforeMinute($datetime = null, int $minute = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('-%d minute', $minute))->getTimestamp(); } /** * 返回传入时间的N分钟后的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $minute 分钟数(默认为1分钟) * @return int 时间戳 */ public static function afterMinute($datetime = null, int $minute = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('+%d minute', $minute))->getTimestamp(); } /** * 返回传入时间的N小时前的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $hour 小时数(默认为1小时) * @return int 时间戳 */ public static function beforeHour($datetime = null, int $hour = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('-%d hour', $hour))->getTimestamp(); } /** * 返回传入时间的N小时后的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $hour 小时数(默认为1小时) * @return int 时间戳 */ public static function afterHour($datetime = null, int $hour = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('+%d hour', $hour))->getTimestamp(); } /** * 返回传入时间的N天前的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $day 天数(默认为1天) * @return int 时间戳 */ public static function beforeDay($datetime = null, int $day = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('-%d day', $day))->getTimestamp(); } /** * 返回传入时间的N天后的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $day 天数(默认为1天) * @return int 时间戳 */ public static function afterDay($datetime = null, int $day = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('+%d day', $day))->getTimestamp(); } /** * 返回传入时间的N星期前的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $week 星期数(默认为1星期) * @return int 时间戳 */ public static function beforeWeek($datetime = null, int $week = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('-%d week', $week))->getTimestamp(); } /** * 返回传入时间的N星期后的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $week 星期数(默认为1星期) * @return int 时间戳 */ public static function afterWeek($datetime = null, int $week = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('+%d week', $week))->getTimestamp(); } /** * 返回传入时间的N月前的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $month 月数(默认为1个月) * @return int 时间戳 */ public static function beforeMonth($datetime = null, int $month = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('-%d month', $month))->getTimestamp(); } /** * 返回传入时间的N月后的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $month 月数(默认为1个月) * @return int 时间戳 */ public static function afterMonth($datetime = null, int $month = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('+%d month', $month))->getTimestamp(); } /** * 返回传入时间的N年前的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $year 年数(默认为1年) * @return int 时间戳 */ public static function beforeYear($datetime = null, int $year = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('-%d year', $year))->getTimestamp(); } /** * 返回传入时间的N年后的时间戳 * @param int|string $datetime 任意格式时间字符串或时间戳(默认为当前时间) * @param int $year 年数(默认为1年) * @return int 时间戳 */ public static function afterYear($datetime = null, int $year = 1): int { $date = new DateTime(); if ($datetime !== null) { $date->setTimestamp(self::toTimestamp($datetime)); } return $date->modify(sprintf('+%d year', $year))->getTimestamp(); } /** * 返回今日开始和结束的时间戳 * * @return array */ public static function today() { list($y, $m, $d) = explode('-', date('Y-m-d')); return [ mktime(0, 0, 0, $m, $d, $y), mktime(23, 59, 59, $m, $d, $y) ]; } /** * 返回昨日开始和结束的时间戳 * * @return array */ public static function yesterday() { $yesterday = date('d') - 1; return [ mktime(0, 0, 0, date('m'), $yesterday, date('Y')), mktime(23, 59, 59, date('m'), $yesterday, date('Y')) ]; } /** * 返回本周开始和结束的时间戳 * * @return array */ public static function week() { list($y, $m, $d, $w) = explode('-', date('Y-m-d-w')); if ($w == 0) $w = 7; //修正周日的问题 return [ mktime(0, 0, 0, $m, $d - $w + 1, $y), mktime(23, 59, 59, $m, $d - $w + 7, $y) ]; } /** * 返回上周开始和结束的时间戳 * * @return array */ public static function lastWeek() { $timestamp = time(); return [ strtotime(date('Y-m-d', strtotime("last week Monday", $timestamp))), strtotime(date('Y-m-d', strtotime("last week Sunday", $timestamp))) + 24 * 3600 - 1 ]; } /** * 返回本月开始和结束的时间戳 * * @return array */ public static function month($everyDay = false) { list($y, $m, $t) = explode('-', date('Y-m-t')); return [ mktime(0, 0, 0, $m, 1, $y), mktime(23, 59, 59, $m, $t, $y) ]; } /** * 返回上个月开始和结束的时间戳 * * @return array */ public static function lastMonth() { $y = date('Y'); $m = date('m'); $begin = mktime(0, 0, 0, $m - 1, 1, $y); $end = mktime(23, 59, 59, $m - 1, date('t', $begin), $y); return [$begin, $end]; } /** * 返回今年开始和结束的时间戳 * * @return array */ public static function year() { $y = date('Y'); return [ mktime(0, 0, 0, 1, 1, $y), mktime(23, 59, 59, 12, 31, $y) ]; } /** * 返回去年开始和结束的时间戳 * * @return array */ public static function lastYear() { $year = date('Y') - 1; return [ mktime(0, 0, 0, 1, 1, $year), mktime(23, 59, 59, 12, 31, $year) ]; } public static function dayOf() { } /** * 获取几天前零点到现在/昨日结束的时间戳 * * @param int $day 天数 * @param bool $now 返回现在或者昨天结束时间戳 * @return array */ public static function dayToNow($day = 1, $now = true) { $end = time(); if (!$now) { list($foo, $end) = self::yesterday(); } return [ mktime(0, 0, 0, date('m'), date('d') - $day, date('Y')), $end ]; } /** * 返回几天前的时间戳 * * @param int $day * @return int */ public static function daysAgo($day = 1) { $nowTime = time(); return $nowTime - self::daysToSecond($day); } /** * 返回几天后的时间戳 * * @param int $day * @return int */ public static function daysAfter($day = 1) { $nowTime = time(); return $nowTime + self::daysToSecond($day); } /** * 天数转换成秒数 * * @param int $day * @return int */ public static function daysToSecond($day = 1) { return $day * 86400; } /** * 周数转换成秒数 * * @param int $week * @return int */ public static function weekToSecond($week = 1) { return self::daysToSecond() * 7 * $week; } }