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

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


当前回答

它是简单的JavaScript和PHP:

即使用户可以打乱他/她的内部时钟和/或时区,我迄今为止发现的最好的方法,以获得偏移量,仍然是新的Date(). gettimezoneoffset();。它是非侵入性的,不会让人头痛,也不需要依赖第三方。

假设我有一个表,users,其中包含一个字段date_created int(13),用于存储Unix时间戳;

假设客户端创建了一个新帐户,数据是通过post接收的,我需要用客户端的Unix时间戳插入/更新date_created列,而不是服务器的。

由于在插入/更新时需要timezoneOffset,因此当客户端提交表单时,它作为额外的$_POST元素传递,从而消除了将其存储在会话和/或cookie中的需要,并且也没有额外的服务器访问。

var off = (-new Date().getTimezoneOffset()/60).toString();//note the '-' in front which makes it return positive for negative offsets and negative for positive offsets
var tzo = off == '0' ? 'GMT' : off.indexOf('-') > -1 ? 'GMT'+off : 'GMT+'+off;

假设服务器接收到tzo为$_POST['tzo'];

$ts = new DateTime('now', new DateTimeZone($_POST['tzo']);
$user_time = $ts->format("F j, Y, g:i a");//will return the users current time in readable format, regardless of whether date_default_timezone() is set or not.
$user_timestamp = strtotime($user_time);

插入/更新date_created = $ user_timestamp。

当检索date_created时,你可以像这样转换时间戳:

$date_created = // Get from the database
$created = date("F j, Y, g:i a",$date_created); // Return it to the user or whatever

现在,这个示例可能适合您的需要,当涉及插入第一个时间戳时……当涉及到额外的时间戳或表时,您可能需要考虑将tzo值插入到用户表中以供将来参考,或者将其设置为会话或cookie。

P.S.但是如果用户旅行并切换时区怎么办?在GMT+4登录,快速移动到GMT-1,然后再次登录。最后一次登录将在将来。

我认为……我们想得太多了。

其他回答

它是简单的JavaScript和PHP:

即使用户可以打乱他/她的内部时钟和/或时区,我迄今为止发现的最好的方法,以获得偏移量,仍然是新的Date(). gettimezoneoffset();。它是非侵入性的,不会让人头痛,也不需要依赖第三方。

假设我有一个表,users,其中包含一个字段date_created int(13),用于存储Unix时间戳;

假设客户端创建了一个新帐户,数据是通过post接收的,我需要用客户端的Unix时间戳插入/更新date_created列,而不是服务器的。

由于在插入/更新时需要timezoneOffset,因此当客户端提交表单时,它作为额外的$_POST元素传递,从而消除了将其存储在会话和/或cookie中的需要,并且也没有额外的服务器访问。

var off = (-new Date().getTimezoneOffset()/60).toString();//note the '-' in front which makes it return positive for negative offsets and negative for positive offsets
var tzo = off == '0' ? 'GMT' : off.indexOf('-') > -1 ? 'GMT'+off : 'GMT+'+off;

假设服务器接收到tzo为$_POST['tzo'];

$ts = new DateTime('now', new DateTimeZone($_POST['tzo']);
$user_time = $ts->format("F j, Y, g:i a");//will return the users current time in readable format, regardless of whether date_default_timezone() is set or not.
$user_timestamp = strtotime($user_time);

插入/更新date_created = $ user_timestamp。

当检索date_created时,你可以像这样转换时间戳:

$date_created = // Get from the database
$created = date("F j, Y, g:i a",$date_created); // Return it to the user or whatever

现在,这个示例可能适合您的需要,当涉及插入第一个时间戳时……当涉及到额外的时间戳或表时,您可能需要考虑将tzo值插入到用户表中以供将来参考,或者将其设置为会话或cookie。

P.S.但是如果用户旅行并切换时区怎么办?在GMT+4登录,快速移动到GMT-1,然后再次登录。最后一次登录将在将来。

我认为……我们想得太多了。

在实际的HTML代码或任何用户代理字符串中没有这样的方法来计算时区,但您可以做的是使用JavaScript创建一个基本函数来获取时区。

我还不知道如何用JavaScript编码,所以我的函数可能需要时间来制作。

但是,您也可以尝试使用JavaScript在Date部分中的getTzimezoneOffset()函数或简单地使用new Date(). gettimezoneoffset();来获得实际的时区。

这里有一种更完整的方法。

获取用户的时区偏移量 测试一些日子的夏令时边界,以确定它们是否在使用夏令时的区域。

节选如下:

function TimezoneDetect(){
    var dtDate = new Date('1/1/' + (new Date()).getUTCFullYear());
    var intOffset = 10000; //set initial offset high so it is adjusted on the first attempt
    var intMonth;
    var intHoursUtc;
    var intHours;
    var intDaysMultiplyBy;

    // Go through each month to find the lowest offset to account for DST
    for (intMonth=0;intMonth < 12;intMonth++){
        //go to the next month
        dtDate.setUTCMonth(dtDate.getUTCMonth() + 1);

        // To ignore daylight saving time look for the lowest offset.
        // Since, during DST, the clock moves forward, it'll be a bigger number.
        if (intOffset > (dtDate.getTimezoneOffset() * (-1))){
            intOffset = (dtDate.getTimezoneOffset() * (-1));
        }
    }

    return intOffset;
}

从JS获取TZ和DST(通过Way Back Machine)

使用PHP日期函数,您将获得网站所在服务器的日期时间。获取用户时间的唯一方法是使用JavaScript。

但是我建议你,如果你的网站有注册要求,那么最好的方法是要求用户注册作为一个强制性的字段。您可以在注册页面中列出各种时区,并将其保存在数据库中。在此之后,如果用户登录到站点,那么您可以根据用户选择的时区为该会话设置默认时区。

可以使用PHP函数date_default_timezone_set设置任何特定的时区。为用户设置指定的时区。

基本上,用户的时区会传到客户端,所以我们必须使用JavaScript。

下面是使用PHP和JavaScript获取用户时区的脚本。

<?php
    #http://www.php.net/manual/en/timezones.php List of Time Zones
    function showclienttime()
    {
        if(!isset($_COOKIE['GMT_bias']))
        {
?>

            <script type="text/javascript">
                var Cookies = {};
                Cookies.create = function (name, value, days) {
                    if (days) {
                        var date = new Date();
                        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                        var expires = "; expires=" + date.toGMTString();
                    }
                    else {
                        var expires = "";
                    }
                    document.cookie = name + "=" + value + expires + "; path=/";
                    this[name] = value;
                }

                var now = new Date();
                Cookies.create("GMT_bias",now.getTimezoneOffset(),1);
                window.location = "<?php echo $_SERVER['PHP_SELF'];?>";
            </script>

            <?php

        }
        else {
          $fct_clientbias = $_COOKIE['GMT_bias'];
        }

        $fct_servertimedata = gettimeofday();
        $fct_servertime = $fct_servertimedata['sec'];
        $fct_serverbias = $fct_servertimedata['minuteswest'];
        $fct_totalbias = $fct_serverbias – $fct_clientbias;
        $fct_totalbias = $fct_totalbias * 60;
        $fct_clienttimestamp = $fct_servertime + $fct_totalbias;
        $fct_time = time();
        $fct_year = strftime("%Y", $fct_clienttimestamp);
        $fct_month = strftime("%B", $fct_clienttimestamp);
        $fct_day = strftime("%d", $fct_clienttimestamp);
        $fct_hour = strftime("%I", $fct_clienttimestamp);
        $fct_minute = strftime("%M", $fct_clienttimestamp);
        $fct_second = strftime("%S", $fct_clienttimestamp);
        $fct_am_pm = strftime("%p", $fct_clienttimestamp);
        echo $fct_day.", ".$fct_month." ".$fct_year." ( ".$fct_hour.":".$fct_minute.":".$fct_second." ".$fct_am_pm." )";
    }

    showclienttime();
?>

但在我看来,最好是询问用户在你的项目中是否必须注册。

不要使用IP地址来明确地确定位置(以及时区)——这是因为使用NAT、代理(越来越流行)和vpn, IP地址不一定真实地反映用户的实际位置,而是反映实现这些协议的服务器所在的位置。

类似于美国的区号对于定位电话用户不再有用,因为号码可携性很流行。

IP地址和上面显示的其他技术对于建议用户可以调整/纠正的默认值很有用。