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

时间:2011-01-05 13:15:19

标签: php mysql time

我有一个Mysql表,其列类型为TIME

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

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

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

谢谢!


更新

我的数据存储在“TIME”类型的mysql表中,而不是“DATETIME”。

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

8 个答案:

答案 0 :(得分:9)

使用ISO 8601hh:mm:ss,以便更好地理解和提高可读性

答案 1 :(得分:3)

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

答案 2 :(得分:2)

通常,您应始终以数据库的本机日期/时间格式存储日期/时间值。这使您可以在查询中使用DB的本机日期/时间操作函数。否则它只是一大块文本而且你仍然坚持使用字符串操作,或者必须选择每个时间字段并在你的应用程序中操作它。

答案 3 :(得分:2)

unix时间戳可能是最常用的,因为它也兼容所有PHP日期/时间函数,并且大小比字符串小。

答案 4 :(得分:1)

没有“标准” - 这实际上取决于您的要求。

但是,如果您需要以规范格式存储日期/时间信息,我建议使用RFC2822(date('r')),因为这样可以确保即使时区因夏令时变化也始终正确,如果那是相关的。

如果这不是一个考虑因素,那么简单地使用时间戳(a.k.a:unixtime - time()的输出)可能就足够了,因为这可以在本机MySQL日期时间格式之间进行简单的转换。 (使用strtotime在PHP中进行转换,或者只使用SQL查询中的UNIX_TIMESTAMPFROM_UNIXTIME MySQL函数。)

答案 5 :(得分:1)

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

唯一的问题是秒不是一个对象,你不能给它提供方便的功能,也不能保持提供的特定分钟数。

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

PHP使用DateInterval

解决了这些问题

41:61:45将存储为

$interval = new DateInterval('PT41H61M45S');

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

在这里,我为你(或任何看的人)创造了一个 (我知道我迟到了,但这个问题在SERP中仍然很突出)

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>'; // +

现在你可以利用MySQL时间轻松地随心所欲地做任何事情。

$time = new Time('864:23:59');
$seconds = $time->toSeconds();
$formatted_time = $time->reformat('%d days %h:%i:%s');

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

答案 6 :(得分:0)

你有很多选择。

PHP有一个很好的函数strtotime,它可以解析许多不同的格式。所以,如果你想保持时间的可读性,那就可以了。

然而,大多数情况下,时间格式存储为自Unix epoch以来的秒数。省去了不得不再次解析的麻烦。

答案 7 :(得分:0)

查看Date/Time classes。他们中的许多人在5.3时获得了大部分的用处,所以如果你被困在那个以下,他们就不会帮助你。