基本上,我几天前玩过我的MySQL数据库,我将时区设置为MST以匹配我的PHP脚本服务器(我还将PHP服务器时区设置为MST) (date_default_timezone_set("MST")
)与数据库匹配)。我有一个需要一个参数的函数,那是一个UNIX时间戳。
function time_elapsed_string($time)
{
$time = time() - $time;
$tokens = array(
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach($tokens as $unit => $text)
{
if($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
这个功能的作用是$time
。它获取当前时间和$ time之间的时间差,并将$time
设置为差异。然后它计算$time
可能存在的最大可能时间戳并回应它。如果它是复数(2周,5个月等),它会在最后添加 s 。
但是,如果我将当前时间作为$time
- 参数,它将回显' [SPACE]前'。我已经用$time = time() - $time;
替换行$time = (time() + 80) - $time;
暂时解决了这个问题,我将当前数字 80 改为5或10,以使其准确无误。
简短说明: 在计算差值时,我必须在当前时间添加秒数,以便它不会回显“ [SPACE]前”。
当我在页面上更新状态时,我正在使用此函数,插入查询被发送到数据库(没有填充时间列),并且因为timestamp列是默认情况下的当前时间戳设置为当前时间戳。
我该如何解决这个问题,因为我真的明白,每天增加5或10个将来都不会稳定。
PS。我不认为我可以重新启动MySQL服务器,因为我在webhost上,我想我没有权利这样做。
EDIT1: 看起来插入的时间戳大约是1分钟,然后是现实生活中。这会导致它吗?
EDIT2: 现在,几个星期后,我需要在100和100之间添加额外200秒以确保 time ago 功能准确无误。
答案 0 :(得分:1)
我不清楚 你是如何将时间戳存储在MySQL中的。至少有三种方法可以在MySQL中存储日期:
DATETIME
TIMESTAMP
前两个选项甚至不考虑数据库服务器的时区。你甚至没有真正说出如何设置时区。
假设您正在使用TIMESTAMP
,您可以使用UNIX_TIMESTAMP(date)函数从MySQL获取unix时间戳。
在MySQL服务器上设置时区设置时,通常最好每个会话进行一次,如下所示:
$sql = "SET names $charset, time_zone='".date("P")."'";
问题的根源似乎是功能本身。每年没有完全“31536000”秒,一个月内也没有“2592000”秒。这是因为一个月内有不同的天数,闰年等等。
这是基于我很久以前写的一个函数(重写它以使其更容易阅读)。希望它对你有用:
function relativeTime($time)
{
$date = getdate($time);
$today = getdate();
$daydiff = $today["mday"]-$date["mday"];
$text = "";
if ($today["mon"] === $date["mon"] && $today["year"] === $date["year"] && $daydiff < 2) {
if ($daydiff === 1) {
$text = sprintf('Yesterday, %s', date('g:i A T', $time));
} else if ($today["hours"] == $date["hours"]) {
$min = $today["minutes"] - $date["minutes"];
if ($min > 1) {
$text = sprintf('%s minutes ago', $min);
} else {
$text = 'A minute ago';
}
} else {
$text = sprintf('Today, %s', date('g:i A T', $time));
}
} else {
$text = date('j F Y - g:i A T', $time);
}
return $text;
}
上述功能仅执行“#minutes ago”和“Today”,“Yesterday”,然后是日期。当然,您可以添加它以使其更加精确。
答案 1 :(得分:1)
由于您根据MySQL中存储的内容做了不同,因此您的选择是:
或者在以下选项中使用UNIX_TIMESTAMP()从MySQL中获取时间:
SELECT *, UNIX_TIMESTAMP() AS unix_timestamp FROM table
SELECT UNIX_TIMESTAMP() AS unix_timestamp
可选的第二个参数是秘密,它可以通过将MySQL的“unix_timestamp”结果传递到第二个可选参数,编码优化的差异(您发现5到10'工作'),或者只是允许PHP时间戳来提供帮助()函数成为服务器同步时上面已经实现的默认值。
无论哪种方式都可以像这样对函数进行简单的更新:
function time_elapsed_string($time, $time0 = NULL)
{
if ($time0 === NULL)
{
$time0 = time();
}
$time = $time0 - $time;
...
示例使用:
time_elapsed_string($recordTimeStamp); // as-is
time_elapsed_string($recordTimeStamp, time() + 5); // an "optimized" difference
time_elapsed_string($recordTimeStamp, $recordUnixTimeStamp); // from MySQL addition
time_elapsed_string($recordTimeStamp, $databaseUnixTimeStamp); // from separate query
答案 2 :(得分:0)
当您插入数据时,如果使用php从time()计算它们,它们将匹配,而不是在现在提前60秒发布时间,而不是使用MySQL CURRENT_TIMESTAMP
。您可以随时使用time() - 1,当您插入时,始终存在至少1秒的差异。
要从日期获取mysql DATETIME格式,请使用此格式,然后将列的值指定为$ date。
$date = date('Y-m-d H:i:s', (time()-1));
在大多数托管环境中,sql server和web服务器是不同的服务器,因此它们之间可能会有一段时间的漂移,但它肯定不应该在一分钟之内,任何值得他们的盐的Web主机都将确保它们都与同一时间服务器同步,因此任何漂移都应以微秒为单位进行测量
答案 3 :(得分:0)
你遇到的问题是因为如果$ time小于1,那么就没有任何较小的面额。
我用if语句修复它,并重命名了一个变量
function time_elapsed_string($time)
{
$time_diff = time() - $time;
$tokens = array(
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second',
);
if ($time_diff < 1)
return '0 seconds';
foreach($tokens as $unit => $text)
{
if($time_diff < $unit) continue;
$numberOfUnits = floor($time_diff / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
您还可以从PHP文档中逐字使用以下内容: 资料来源:http://php.net/manual/en/function.time.php
以人类可读的形式获得时间的两种快速方法。
function time_elapsed_A($secs){
$bit = array(
'y' => $secs / 31556926 % 12,
'w' => $secs / 604800 % 52,
'd' => $secs / 86400 % 7,
'h' => $secs / 3600 % 24,
'm' => $secs / 60 % 60,
's' => $secs % 60
);
foreach($bit as $k => $v)
if($v > 0)$ret[] = $v . $k;
return join(' ', $ret);
}
function time_elapsed_B($secs){
$bit = array(
' year' => $secs / 31556926 % 12,
' week' => $secs / 604800 % 52,
' day' => $secs / 86400 % 7,
' hour' => $secs / 3600 % 24,
' minute' => $secs / 60 % 60,
' second' => $secs % 60
);
foreach($bit as $k => $v){
if($v > 1)$ret[] = $v . $k . 's';
if($v == 1)$ret[] = $v . $k;
}
array_splice($ret, count($ret)-1, 0, 'and');
$ret[] = 'ago.';
return join(' ', $ret);
}
$nowtime = time();
$oldtime = 1335939007;
echo "time_elapsed_A: ".time_elapsed_A($nowtime-$oldtime)."\n";
echo "time_elapsed_B: ".time_elapsed_B($nowtime-$oldtime)."\n";
/** Output:
time_elapsed_A: 6d 15h 48m 19s
time_elapsed_B: 6 days 15 hours 48 minutes and 19 seconds ago.
**/
答案 4 :(得分:0)
您写道:
“但是,如果我将当前时间作为$ time-parameter,它将回显'[SPACE]前”。
所以在这种情况下你的$ time参数将等于time()。 在你的函数体中这一行:
$time = time() - $time;
实际上是$ time = time() - time(); 这是0,因为两次time()调用之间不会经过1秒(通常)。
我认为如果你使用php DateTime对象会更好。
$now = new DateTime();
$timeObject = new DateTime();
$timeObject->setTimestamp($time);
// DateInterval object created by DateTime::diff()
$diff = $now->diff($timeObject);
// Number of years.
echo $diff->y;
// Number of months.
echo $diff->m;
// Number of days.
echo $diff->d;
// Number of hours.
echo $diff->h;
// Number of minutes.
echo $diff->i;
// Number of seconds.
echo $diff->s;