我有一个Mysql表,其列类型为TIME 。
当我使用PHP检索此TIME列的值时,我应该如何将它存储在php变量中以供以后在我的php类中使用?
我想用标准的php 5处理时间的方式。
谢谢!
更新
我的数据存储在“TIME”类型的mysql表中,而不是“DATETIME”。
我只想处理时间(一些小时,分钟和秒)。日期与我的情况无关,因此 unix时间戳或日期/时间对象似乎不合适。
答案 0 :(得分:9)
使用ISO 8601,hh: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_TIMESTAMP或FROM_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时获得了大部分的用处,所以如果你被困在那个以下,他们就不会帮助你。