是否有一种标准的方法可以让服务器在网页中确定用户的时区?

可能来自HTTP报头或用户代理字符串的一部分?


当前回答

我认为@Matt Johnson-Pints是目前为止最好的,CanIuse搜索显示它现在被广泛采用:

.timeZone .resolvedOptions https://caniuse.com/?search=Intl.DateTimeFormat () ()

其中一个挑战是考虑为什么要知道时区。因为我认为大多数人忽略了一件事,那就是他们是可以改变的!如果一个用户带着他的笔记本电脑从欧洲旅行到美国,如果你之前把它存储在数据库中,那么他们的时区现在是不正确的(即使用户从来没有更新过他们的设备时区)。这也是@Mads Kristiansen回答的问题,因为用户会旅行——你不能把它当作给定的。

例如,我的Linux笔记本电脑关闭了“自动时区”。虽然时间可能会更新我的时区却不会。

所以我相信答案是——你需要它做什么?客户端似乎提供了一种更简单的方法来确定它,但是客户端和服务器端代码都将依赖于用户更新他们的时区或自动更新。我当然可能是错的。

其他回答

-new Date().getTimezoneOffset()/60;

getTimezoneOffset()方法将从GMT减去您的时间并返回分钟数。如果你住在GMT-8,它会返回480。

把它换算成小时,除以60。此外,请注意,符号与您需要的相反——它计算的是GMT与您的时区的偏移量,而不是您的时区与GMT的偏移量。要解决这个问题,只需乘以-1。

还要注意w3school说:

返回值不是一个常量,因为使用的惯例 日光节约时间。

JavaScript:

function maketimus(timestampz)
{
    var linktime = new Date(timestampz * 1000);
    var linkday = linktime.getDate();
    var freakingmonths = new Array();

    freakingmonths[0]  = "jan";
    freakingmonths[1]  = "feb";
    freakingmonths[2]  = "mar";
    freakingmonths[3]  = "apr";
    freakingmonths[4]  = "may";
    freakingmonths[5]  = "jun";
    freakingmonths[6]  = "jul";
    freakingmonths[7]  = "aug";
    freakingmonths[8]  = "sep";
    freakingmonths[9]  = "oct";
    freakingmonths[10] = "nov";
    freakingmonths[11] = "dec";

    var linkmonthnum = linktime.getMonth();
    var linkmonth = freakingmonths[linkmonthnum];
    var linkyear = linktime.getFullYear();
    var linkhour = linktime.getHours();
    var linkminute = linktime.getMinutes();

    if (linkminute < 10)
    {
        linkminute = "0" + linkminute;
    }

    var fomratedtime = linkday + linkmonth + linkyear + " " +
                       linkhour + ":" + linkminute + "h";
    return fomratedtime;
}

只需将您的时间以Unix时间戳格式提供给该函数即可;JavaScript已经知道用户的时区。

是这样的:

PHP:

echo '<script type="text/javascript">
var eltimio = maketimus('.$unix_timestamp_ofshiz.');
document.write(eltimio);
</script><noscript>pls enable javascript</noscript>';

这将始终显示正确的时间基于时区的人已设置在他/她的计算机时钟。没有必要向任何人索取任何东西,把它保存到合适的地方,感谢上帝!

所有的魔力似乎都在

visitortime.getTimezoneOffset()

真酷,我还不知道呢。它能在ie浏览器上运行吗?从这里你应该能够使用JavaScript到Ajax,设置cookie等等。我自己可能也会吃饼干。

不过,您需要允许用户更改它。我们曾尝试使用地理定位(通过maxmind)来实现这一点,但这是错误的,不值得这么做。所以我们让用户在他们的配置文件中设置它,并向还没有设置的用户显示一个通知。

使用Unkwntech的方法,我用jQuery和PHP编写了一个函数。这是经过测试和工作!

在您希望将时区作为变量的PHP页面上,在页面顶部附近放置以下代码片段:

<?php
    session_start();
    $timezone = $_SESSION['time'];
?>

这将读取会话变量“time”,这是我们现在将要创建的。

在同一个页面上,在<head>中,首先需要包含jQuery:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

同样在<head>, jQuery下面,粘贴这个:

<script type="text/javascript">
    $(document).ready(function() {
        if("<?php echo $timezone; ?>".length==0){
            var visitortime = new Date();
            var visitortimezone = "GMT " + -visitortime.getTimezoneOffset()/60;
            $.ajax({
                type: "GET",
                url: "http://example.org/timezone.php",
                data: 'time='+ visitortimezone,
                success: function(){
                    location.reload();
                }
            });
        }
    });
</script>

您可能注意到,也可能没有注意到,但是您需要将URL更改为您实际的域。

最后一件事。你可能想知道timezone.php到底是什么。其实很简单: (创建一个名为timezone.php的新文件,并使用上面的URL指向它)

<?php
    session_start();
    $_SESSION['time'] = $_GET['time'];
?>

如果工作正常,它将首先加载页面,执行JavaScript,然后重新加载页面。然后,您将能够读取$timezone变量并随心所欲地使用它!它返回当前UTC/GMT时区偏移量(GMT -7)或您所在的任何时区。

你可以在客户端使用moment-timezone将值发送给服务器;示例用法:

> moment.tz.guess()
"America/Asuncion"