Как сохранить значения "только время" с помощью php?

У меня есть таблица MySQL, которая имеет столбец типа TIME.

когда я получаю значения этого столбца времени с PHP, как я должен хранить его в переменной php для последующего использования в моих классах php?

  • должен ли я сохранить его как строку: "12: 45: 23"?
  • должен ли я преобразовать его в долю дня : 0.25 is 06:00:00 ?
  • должен ли я конвертировать его в несколько секунд: 15152 is 04: 12 : 32 ?
  • другое?

Я хотел бы использовать стандартный php 5 способ работы со временем.

спасибо!


обновление

мои данные хранятся в таблице mysql типа "время", а не"DATETIME".

Я просто хочу разобраться с времени (количество часов, минут и секунд). дата не имеет значения в моем случае, поэтому метка времени unix или объекты даты / времени, похоже, не соответствующий.

8 ответов


лучшим и наиболее распространенным способом является количество секунд, так как все функции php работают в этом формате. Также смотрите: "unix timestamp"


использовать ISO 8601, которая составляет hh:mm:ss для лучшего понимания и высокой readbility


В общем случае вы всегда должны хранить значение даты/времени в собственных форматах даты / времени базы данных. Это позволяет использовать собственные функции управления датой/временем БД в запросах. В противном случае это просто кусок текста, и вы застряли с использованием манипуляции строками или должны выбирать каждое поле времени и манипулировать им в своем приложении.


метка времени unix, вероятно, лучше всего подходит для наиболее распространенного использования, поскольку она также совместима со всеми функциями даты/времени PHP и меньше по размеру, чем строка.


нет стандарта "" - это действительно зависит от ваших требований.

однако, если вам нужно хранить информацию о дате / времени в каноническом формате, я бы рекомендовал использовать RFC2822 (date('r')), Так как это гарантирует, что это всегда правильно, даже когда часовой пояс изменяется из-за летнего времени и т. д. если это важно.

Если это не рассмотрение, то просто с помощью метки времени (a.к. a: unixtime-выход time()) вполне может оказаться достаточным, как это может быть тривиально преобразуется между собственным форматом datetime MySQL. (Используйте strtotime конвертировать в PHP или просто использовать UNIX_TIMESTAMP или FROM_UNIXTIME функции MySQL в SQL-запросе.)


есть много вариантов у вас есть.

PHP имеет хорошую функцию strtotime это может анализировать много разных форматов. Так что, если вы хотите, чтобы время читалось, вы можете.

чаще всего, однако, формат времени сохраняется как количество секунд с момента эпохи Unix. Избавляет от необходимости постоянно анализировать снова.


посмотреть в классы даты / времени. Многие из них получили большую часть своей полезности в 5.3, поэтому, если вы застряли ниже этого, они вам не помогут.


время-это интервал, поэтому вы можете сохранить его как секунды.

единственное, что секунды не являются объектом, и вы не можете дать ему удобные функции, а также не поддерживать определенное количество минут.

например, скажем, вы используете время, как 45:61:59, после преобразования его в секунды вы не сможете преобразовать его обратно в этот формат.

PHP решает эти проблемы с помощью DateInterval

41:61:45 будет храниться в

$interval = new DateInterval('PT41H61M45S');

проблема в том, что DateInterval не так прост в использовании и полезен, как это может быть, так почему бы не создать свой собственный класс?

вот, я создал один только для вас (или кто-нибудь ищет)
(Я знаю, что опоздал, но этот вопрос все еще всплывает высоко в SERPs)

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');

Не стесняйтесь, чтобы изменить это и сделать его короче или лучше