使用php存储"仅时间"值的方法是什么?

ben*_*ail 8 php mysql time

我有一个Mysql表,其中有一个TIME类型的列.

当我使用PHP检索此TIME列的值时,我应该如何将其存储在php变量中以供以后在我的php类中使用?

  • 我应该把它保持为字符串:"12:45:23"?
  • 我应该把它转换成一天的一小部分:0.25是06:00:00吗?
  • 我应该将其转换为秒数:15152是04:12:32吗?
  • 其他?

我想用标准的php 5处理时间的方式.

谢谢!


UPDATE

我的数据存储在"TIME"类型的mysql表中,而不是"DATETIME".

我只想处理时间(数小时,分钟和秒).日期与我的情况无关,因此unix时间戳或日期/时间对象似乎不合适.

ajr*_*eal 9

使用ISO 8601,这是hh:mm:ss为了更好地理解和高可读性

  • 是的,这没有什么不对,很大程度上取决于你的应用程序需求,一些答案表明时间戳显然有点过分,如果你的应用程序只处理数小时,这是不理想的.有理由说mysql有日期,日期时间,时间戳,时间...各种数据类型是为了满足不同的目的 (3认同)

Sim*_*mon 6

最好和最常见的方法是秒数,因为所有 php 函数都以这种格式工作。另请参阅:“Unix 时间戳”

  • Unix 时间戳还包含有关日期的信息,但这里似乎不是合适的解决方案。 (6认同)

Tim*_*nen 5

时间是一个间隔,因此您可以将其存储为秒。

唯一的问题是秒不是一个对象,你不能给它提供方便的函数,它也不能维护所提供的具体分钟数。

例如,假设您使用类似 的时间45:61:59,将其转换为秒后,您将无法将其转换回这种格式。

PHP 使用以下方法解决了这些问题DateInterval

41:61:45将被存储为

$interval = new DateInterval('PT41H61M45S');
Run Code Online (Sandbox Code Playgroud)

问题是它DateInterval并不那么容易使用或有用,那么为什么不创建自己的类呢?

在这里,我专门为您(或任何正在寻找的人)创建了一个
(我知道我迟到了,但这个问题仍然在 SERP 中出现得很高)

$interval = new DateInterval('PT41H61M45S');
Run Code Online (Sandbox Code Playgroud)

现在您可以花点时间轻松地用 MySQL 做任何您想做的事情。

class Time extends DateInterval {
    const SEC_IN_MINUTE = 60;
    const SEC_IN_HOUR = 3600;
    const SEC_IN_DAY = 86400;
    const SEC_IN_YEAR = 31536000;

    private $interval, $time;

    // takes an $time input of 48:23:12 or seconds or DateInterval spec
    public function __construct($time){
        // support interval spec format
        if (strpos($time, 'P') === 0) {
            parent::__construct($time);

        } else

        // support seconds
        if (is_int($time)) {
            parent::__construct('PT' . $time . 'S');

        } else
        // support 00:00:00 format
        if (preg_match('/([0-9]+):([0-9]+):([0-9]+)/', $time, $match)) {
            $this->time = $time;
            $this->h = (int)$match[1];
            $this->i = (int)$match[2];
            $this->s = (int)$match[3];
            parent::__construct('PT' . $this->h . 'H' . $this->i . 'M' . $this->s . 'S');
        // support human format
        // e.g. "5 minutes"
        } elseif(strtotime($time)) {
            $dt = new DateTime('@0', new DateTimeZone('UTC'));
            $dt->modify($time);
            parent::__construct('PT' . $dt->getTimeStamp() . 'S');
        }else {
            throw new Exception('"' . $time . '" is an unknown time format');
        }
    }
    public function toSeconds(){
        $zero = new DateTime('@0'); // zero date
        return $zero->add($this)->getTimestamp();
    }
    public function toMinutes(){
        return $this->toSeconds() / 60;
    }
    public function toHours(){
        return $this->toMinutes() / 60;
    }
    public function toDays(){
        return $this->toHours() / 24;
    }
    public function toYears(){
        return $this->toHours() / 365;
    }

    // recalculate carry over points
    // this is to convert a time like 22:98:74 to 23:39:14
    // warning: intervals don't know how long a month is, and as such can't support them
    public function recalculate()
    {
        $zero = new DateTime('@0'); // zero date
        $to = clone $zero;
        $to = $to->add($this);
        $diff = $zero->diff($to);
        foreach ($diff as $k => $v) $this->$k = $v;

        $dt = new DateTime('@0'); // zero date
        $dt->add(new self('P'.$this->m.'M'));
        $seconds = $dt->getTimeStamp();

        // add what was months to days
        $this->m = 0;
        $this->d += $seconds / 86400;

        // move excess days to years 
        if($this->d > 365){
            $this->y = floor($this->d / 365);
            $this->d = $this->d % 365;
        }

        return $this;
    }

    // remove all whole chunks of interval from seconds and return the amount of chunks
    protected function popTimeSpan(&$seconds, $interval){
        $timespan = $seconds / $interval;
        $timespan = floor($timespan);
        $seconds -= $timespan * $interval;
        return $timespan;
    }

    // a special version of format() that will maintain the full interval in the formatted string
    // warning: it does not support %m or %M, which will always be converted to 0
    public function reformat($format){

        $seconds = $this->toSeconds();


        if(strpos($format, '%y')!==false || strpos($format, '%Y')!==false){
            $timespan = self::popTimeSpan($seconds, self::SEC_IN_YEAR);
            $format = str_replace('%y', $timespan, $format);
            $format = str_replace('%Y', str_pad($timespan,4,'0',STR_PAD_LEFT), $format);
        }
        if(strpos($format, '%m')!==false || strpos($format, '%M')!==false){
            $format = str_replace('%m', '0', $format);
            $format = str_replace('%M', '00', $format);
        }
        if(strpos($format, '%d')!==false || strpos($format, '%D')!==false){
            $timespan = self::popTimeSpan($seconds, self::SEC_IN_DAY);
            $format = str_replace('%d', $timespan, $format);
            $format = str_replace('%D', str_pad($timespan,2,'0',STR_PAD_LEFT), $format);
        }
        if(strpos($format, '%h')!==false || strpos($format, '%H')!==false){
            $timespan = self::popTimeSpan($seconds, self::SEC_IN_HOUR);
            $format = str_replace('%h', $timespan, $format);
            $format = str_replace('%H', str_pad($timespan,2,'0',STR_PAD_LEFT), $format);
        }
        if(strpos($format, '%i')!==false || strpos($format, '%I')!==false){
            $timespan = self::popTimeSpan($seconds, self::SEC_IN_MINUTE);
            $format = str_replace('%i', $timespan, $format);
            $format = str_replace('%I', str_pad($timespan,2,'0',STR_PAD_LEFT), $format);
        }
        if(strpos($format, '%s')!==false || strpos($format, '%S')!==false){
            $timespan = floor($seconds);
            $format = str_replace('%s', $timespan, $format);
            $format = str_replace('%S', str_pad($timespan,2,'0',STR_PAD_LEFT), $format);
        }

        return $this->format($format);
    }
}

$time = new Time('23:10:15');
echo 'Seconds: '.$time->s.'<br>'; // 15
echo 'toSeconds: '.$time->toSeconds().'<br>'; // 83415

// lets try with times that are above 24 hour
$time = new Time('48:10:16');
echo 'Seconds: '.$time->s.'<br>'; // 16
echo 'toSeconds: '.$time->toSeconds().'<br>'; // 173416

// lets try with times that are messy
$time = new Time('23:98:75');
echo 'Seconds: '.$time->s.'<br>'; // 75
echo 'toSeconds: '.$time->toSeconds().'<br>'; // 88755
echo 'Formatted: '.$time->format('%Y-%d %H:%i:%s').'<br>'; // 00-0 23:98:75
echo 'Recalculated: '.$time->reformat('%Y-%d %H:%i:%s').'<br>'; // 0000-1 00:39:15

// lets try with months!!
$time = new Time('13044:98:74');
echo 'Seconds: '.$time->s.'<br>'; // 74
echo 'toSeconds: '.$time->toSeconds().'<br>'; // 46964354
echo 'Formatted: '.$time->format('%Y-%d %H:%i:%s').'<br>'; //  00-0 13044:98:74
echo 'Recalculated: '.$time->reformat('%Y-%d %H:%i:%s').'<br>'; // 0001-178 13:39:14


// ok, now with years
$time = new Time('87630:98:74'); // 10 years, 30 hours 98 minutes  and 74 seconds
echo 'Time: 87630:98:74<br>';
echo 'Formatted at year level: '.$time->format('%Y-%d %H:%i:%s').'<br>'; // 00-0 87630:98:74
echo 'Formatted at day level: '.$time->format('%d %H:%i:%s').'<br>'; // 0 87630:98:74
echo 'Formatted at hour level: '.$time->format('%H:%i:%s').'<br>'; // 87630:98:74
echo 'Formatted at minute level: '.$time->format('%i:%s').'<br>'; // 98:74
echo 'Formatted at second level: '.$time->format('%s seconds').'<br>'; // 74 seconds
echo 'Formatted at year + second level: '.$time->format('%y years %s seconds').'<br>'; // 0 years 74 seconds

echo 'Recalculated at year level: '.$time->reformat('%Y-%d %H:%i:%s').'<br>'; // 0010-1 07:39:14
echo 'Recalculated at day level: '.$time->reformat('%d %H:%i:%s').'<br>'; // 3651 07:39:14
echo 'Recalculated at hour level: '.$time->reformat('%H:%i:%s').'<br>'; // 87631:39:14
echo 'Recalculated at minute level: '.$time->reformat('%i:%s').'<br>'; // 5257899:14
echo 'Recalculated at second level: '.$time->reformat('%s seconds').'<br>'; // 315473954 seconds
echo 'Recalculated at year + second level: '.$time->reformat('%y years %s seconds').'<br>'; // 10 years 113954 seconds

echo 'Test %a: '.$time->reformat('%a').'<br>'; // (unknown)
echo 'Test %R: '.$time->reformat('%r').'<br>'; // 
echo 'Test %r: '.$time->reformat('%R').'<br>'; // +
Run Code Online (Sandbox Code Playgroud)

请随意编辑它并使其更短或更好