<?php
namespace fast;
class Date
{
const YEAR = 31536000;
const MONTH = 2592000;
const WEEK = 604800;
const DAY = 86400;
const HOUR = 3600;
const MINUTE = 60;
/**
* 计算两个时区间相差的时长,单位为秒
*
* $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)
{
$local = date_default_timezone_get();
}
if (is_int($now))
{
$now = date(DateTime::RFC2822, $now);
}
$zone_remote = new DateTimeZone($remote);
$zone_local = new DateTimeZone($local);
$time_remote = new DateTime($now, $zone_remote);
$time_local = new DateTime($now, $zone_local);
$offset = $zone_remote->getOffset($time_remote) - $zone_local->getOffset($time_local);
return $offset;
}
public static function span($remote, $local = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
{
$output = trim(strtolower((string) $output));
if (!$output)
{
return FALSE;
}
$output = preg_split('/[^a-z]+/', $output);
$output = array_combine($output, array_fill(0, count($output), 0));
extract(array_flip($output), EXTR_SKIP);
if ($local === NULL)
{
$local = time();
}
$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));
}
if (isset($output['seconds']))
{
$output['seconds'] = $timespan;
}
if (count($output) === 1)
{
return array_pop($output);
}
return $output;
}
public static function human($remote, $local = null)
{
$timediff = (is_null($local) || $local ? time() : $local) - $remote;
$chunks = array(
array(60 * 60 * 24 * 365, 'year'),
array(60 * 60 * 24 * 30, 'month'),
array(60 * 60 * 24 * 7, 'week'),
array(60 * 60 * 24, 'day'),
array(60 * 60, 'hour'),
array(60, 'minute'),
array(1, 'second')
);
for ($i = 0, $j = count($chunks); $i < $j; $i++)
{
$seconds = $chunks[$i][0];
$name = $chunks[$i][1];
if (($count = floor($timediff / $seconds)) != 0)
{
break;
}
}
return __("%d {$name}%s ago", $count, ($count > 1 ? 's' : ''));
}
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'));
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':
$time = $position ?
mktime(0, 0, 0, $month, $day - date("w", mktime(0, 0, 0, $month, $day, $year)) + 1 - 7 * (-$offset), $year) :
mktime(23, 59, 59, $month, $day - date("w", mktime(0, 0, 0, $month, $day, $year)) + 7 - 7 * (-$offset), $year);
break;
case 'month':
$time = $position ? mktime(0, 0, 0, $month + $offset, 1, $year) : mktime(23, 59, 59, $month + $offset, cal_days_in_month(CAL_GREGORIAN, $month + $offset, $year), $year);
break;
case 'quarter':
$time = $position ?
mktime(0, 0, 0, 1 + ((ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) - 1) * 3, 1, $year) :
mktime(23, 59, 59, (ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 3) + $offset) * 3, cal_days_in_month(CAL_GREGORIAN, (ceil(date('n', mktime(0, 0, 0, $month, $day, $year)) / 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;
}
}