【问题标题】:show server time including timezone offset显示服务器时间,包括时区偏移
【发布时间】:2015-05-30 20:56:52
【问题描述】:

我在使用 php 和 js 显示服务器的实际时间时遇到了一些困难。
在服务器端,我有以下 php 代码:

$date = new DateTime();
echo $date->getTimestamp();

在客户端,如果有以下 js 代码更改 div 的内容以显示当前时间:

flag = true;
timer = '';


function clock()
{
        if ( flag ) {
            xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", "backend/time_backend.php?action=serverTime", false);
            xmlhttp.send();

            var stamp = xmlhttp.responseText;


            timer = stamp*1000;
        }
        var d = new Date(timer);

        var hours = d.getHours();
        var minutes = d.getMinutes();
        var seconds = d.getSeconds();

        //hours = hours % 12;
        //hours = hours ? hours : 12; // the hour ’0' should be ’12'
        minutes = minutes < 10 ? '0'+minutes : minutes;
        seconds = seconds < 10 ? '0'+seconds : seconds;
        var strTime = hours + ':' + minutes + ':' + seconds;
        document.getElementById("clock").innerHTML= strTime ;

        flag = false;
        timer = timer + 1000;
}

window.onload = function() {
    setInterval(clock, 1000);
};

只要服务器的时区和我的时区相同,它就可以工作。但是一旦我更改了服务器上的时区,它就不再起作用了。它仍然会显示我的本地客户端时间,尽管服务器上的 bash 命令date 显示正确偏移的时间。

我该如何解决这个问题?我真的需要显示服务器本地时间。

【问题讨论】:

  • 这有帮助吗? stackoverflow.com/a/6621656/989920 我认为问题不在于 JS,因为这只是转换服务器提供的时间戳。问题可能出在time_backend.php 中提供时间戳的代码上。

标签: javascript php time


【解决方案1】:

Date::getTimestamp 总是返回Unix timestamp。 Unix 时间戳不存储时区信息。

解决方案是根据服务器提供的日期信息构建 JavaScript Date 对象。

注意:当服务器或客户端更改时区(即 DST)时,时间不会不同步。如果避免请求后端,更准确的解决方案是在 JavaScript 中使用时区库(例如timezone.js)。

PHP:

$date = new DateTime;

echo json_encode(array(
    'year' => (int) $date->format('Y'),
    'month' => (int) $date->format('m'),
    'day' => (int) $date->format('j'),
    'hours' => (int) $date->format('H'),
    'minutes' => (int) $date->format('i'),
    'seconds' => (int) $date->format('s'),
));

JavaScript:

var date = null;

function updateTime() {
    if (!date) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET", "backend/time_backend.php?action=serverTime", false);
        xmlhttp.send();

        var j = JSON.parse(xmlhttp.responseText);
        date = new Date(
            j['year'], j['month'],
            j['day'], j['hours'],
            j['minutes'], j['seconds']
        );

        return;
    }

    // Increment time by 1 second
    date.setTime(date.getTime() + 1000);
}

function clock() {
    updateTime();

    var hours = date.getHours();
    var minutes = date.getMinutes();
    var seconds = date.getSeconds();

    hours = hours % 12;
    hours = hours ? hours : 12; // the hour ’0' should be ’12'
    minutes = minutes < 10 ? '0'+minutes : minutes;
    seconds = seconds < 10 ? '0'+seconds : seconds;
    var strTime = hours + ':' + minutes + ':' + seconds;
    document.getElementById('clock').innerHTML = strTime;
}

window.onload = function() {
    setInterval(clock, 1000);
};

【讨论】:

    【解决方案2】:

    您正在从 PHP 发送 unix 时间戳 可能是在使用

    echo date("Y-m-d H:i:s", time());
    

    如果你想使用字符串来使用JS创建日期对象。

    你的 JS 代码应该是

    function clock()
    {
        if ( flag ) {
            xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", "backend/time_backend.php?action=serverTime", false);
            xmlhttp.send();
    
            var stamp = xmlhttp.responseText;
    
            var timer = new Date(stamp);
        }
        var d = new Date(timer);
    
        var hours = d.getHours();
        var minutes = d.getMinutes();
        var seconds = d.getSeconds();
    
        //hours = hours % 12;
        //hours = hours ? hours : 12; // the hour ’0' should be ’12'
        minutes = minutes < 10 ? '0'+minutes : minutes;
        seconds = seconds < 10 ? '0'+seconds : seconds;
        var strTime = hours + ':' + minutes + ':' + seconds;
        document.getElementById("clock").innerHTML= strTime ;
    
        flag = false;
        timer = new Date(timer.getTime() + 1000);
    }
    

    【讨论】:

    • 你不需要做"timer = stamp*1000;"随着时间的推移以预期的形式出现。
    • 但这假设每秒从服务器请求时间。
    • 必须对您的代码进行更多更新 - 看看上面的版本是否有效。顺便说一句,我假设您的 ajax 调用有 200 响应,响应的日期值格式为“2015-03-26 18:02:15” 请务必在浏览器控制台中进行检查。
    • 这成功了!耶!我认为,使这项工作起作用的事实是,您没有像@pixeleet 的 ISO 8601 格式那样将 UTC 偏移量附加到日期时间字符串。因此,客户无法计算本地时间的日期......这至少是我的猜测;)谢谢! :)
    【解决方案3】:

    您可以使用 ISO 8601 格式的日期。

    $date = date("c", time());
    

    会给你一个。

    ISO 8601 数据元素和交换格式 - 信息 交换 – 日期和时间的表示是国际性的 涵盖日期和时间相关数据交换的标准。它是 由国际标准化组织 (ISO) 和 于 1988 年首次发布。本标准的目的是 提供一种明确且定义明确的日期表示方法 和时间,以避免对数字表示的误解 日期和时间,尤其是当数据在 具有不同书写数字日期约定的国家和地区 次。

    然后您可以执行Date.parse() ,其中将返回一个时间戳;)然后像收到时间戳一样继续操作。

    【讨论】:

    • 遗憾的是,js 仍然显示客户端本地时间。 console.log(stamp) 打印2015-03-26T20:44:16+02:00(布加勒斯特时区),浏览器显示19:44:16(这是我的当地时间,柏林时区)。
    • 好的,我看到了你的问题:) 很痛苦,javascript 总是会尝试将它转换为你的本地时间。所以你可以做些什么来减轻你的痛苦。因为直接执行new Date(stamp) 也会导致转换为您的本地时区。您跟踪与您的时区相比的偏移量。然后你必须从时间戳中添加或减去它:(如果我得到它并且你试图显示服务器上而不是客户端上的时间。对吧?:)
    • 是的,你是对的。但是,在不提供偏移量的情况下定义日期时间格式。见雅各布的回答;)
    猜你喜欢
    • 2012-09-02
    • 1970-01-01
    • 2019-04-13
    • 2016-03-04
    • 2016-11-25
    • 2013-01-21
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多