2

所以基本上,几天前我玩弄了我的 MySQL 数据库,并将时区设置为 MST 以与我的 PHP 脚本所在的服务器相匹配(我还将 PHP-server 时区设置为 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]ago ”。我已经暂时解决了这个问题,方法是用我将当前数字 80 增加 5 或 10 的行替换$time = time() - $time;$time = (time() + 80) - $time;使其准确

简短说明: 在计算要产生的差异时,我必须在当前时间上添加秒数,这样它就不会只回显“ [SPACE]ago ”。

当我更新页面上的状态时,我正在使用此功能,插入查询被发送到数据库(没有填充时间列)并且因为时间戳列是默认的当前时间戳,它被设置为当前时间戳。

我该如何解决这个问题,因为我真的明白每天添加 5 或 10 不会在未来稳定。

PS。我不认为我可以重新启动我的 MySQL 服务器等,因为我在一个网络主机上,我想我没有这样做的正确权限。

EDIT1: 看起来插入的时间戳大约提前 1 分钟,然后在现实生活中。这可能是造成它的原因吗?

EDIT2: 现在,几周后,我需要额外增加 100 到 200 秒,以确保时间前功能是准确的。

4

5 回答 5

1

我不清楚的是您如何将时间戳存储在 MySQL 中。在 MySQL 中存储日期至少有三种方法:

  1. 作为 int - time() 的输出
  2. 作为DATETIME
  3. 作为TIMESTAMP

前两个选项甚至没有考虑数据库服务器的时区。您甚至都没有真正说出您是如何设置时区的。

假设您正在使用 a ,您可以使用UNIX_TIMESTAMP(date)函数TIMESTAMP从 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;
}

上面的函数只执行“# 分钟前”和“今天”、“昨天”,然后是日期。当然,您可以添加它以使其更加精确。

于 2013-08-05T23:13:24.333 回答
1

由于您正在根据 MySQL 中存储的内容进行差异化,因此您的选择是:

  1. 在您的服务器上使用网络时间协议(请参阅http://pool.ntp.org/),并希望最好...
  2. 或者在如下选项中使用UNIX_TIMESTAMP()从 MySQL 获取时间:

    • 在您的查询中:SELECT *, UNIX_TIMESTAMP() AS unix_timestamp FROM table
    • 或单独调用:SELECT UNIX_TIMESTAMP() AS unix_timestamp

可选的第二个参数是秘密,它可以通过将 MySQL 的“unix_timestamp”结果传递到第二个可选参数,编码优化的差异(你发现 5 到 10 'working'),或者简单地允许 PHP timestamp() 函数来提供帮助当您的服务器同步时,成为上面已经实现的默认值。

无论哪种方式,都可以像这样对函数进行简单的更新:

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
于 2013-08-08T18:56:36.880 回答
0

插入数据时不要使用 MySQL CURRENT_TIMESTAMP,如果使用 php 从 time() 计算它,它们将匹配,并且您不会提前 60 秒获得发布时间。当您以这种方式插入时,您始终可以使用 time()-1,总会有至少 1 秒的差异。

要从日期获取 mysql DATETIME 格式,只需使用它,然后将列的值指定为 $date。

$date = date('Y-m-d H:i:s', (time()-1));

在大多数托管环境中,sql server 和 web 服务器是不同的服务器,因此它们之间可能会有一些时间偏移,但肯定不应该在一分钟左右,任何值得他们盐分的 web 主机都将确保它们都同步同一时间服务器,因此任何漂移都应以微秒为单位进行测量

于 2013-07-11T12:43:01.593 回答
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.
**/
于 2013-08-06T17:37:35.503 回答
0

你写了:

“但是,如果我将当前时间作为 $time 参数,它会回显 '[SPACE]ago'。”

所以在这种情况下,你的 $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;
于 2013-08-08T08:09:17.463 回答