Определить часовой пояс пользователя - PullRequest
574 голосов
/ 01 августа 2008

Существует ли для веб-сервера стандартный способ определения часового пояса пользователя на веб-странице?

Возможно из HTTP-заголовка или части строки user-agent?

Ответы [ 24 ]

21 голосов
/ 16 сентября 2010

С помощью функции PHP date вы получите дату и время сервера, на котором расположен сайт. Единственный способ получить пользовательское время - использовать 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();
?>

Но, с моей точки зрения, лучше спросить пользователей, является ли регистрация обязательной в вашем проекте.

19 голосов
/ 28 августа 2011

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>';

Это всегда будет правильно показывать время в зависимости от часового пояса, который человек установил на своих часах компьютера. Слава богу, что никому ничего не нужно просить и сохранять на местах!

19 голосов
/ 27 мая 2012

Легко, просто используйте функцию JavaScript getTimezoneOffset следующим образом:

-new Date().getTimezoneOffset()/60;
18 голосов
/ 02 января 2013

Не используйте IP-адрес для окончательного определения местоположения (и, следовательно, часового пояса) - это потому, что с NAT, прокси (все более популярными) и VPN, IP-адреса не обязательно реалистично отражают фактическое местоположение пользователя, но местоположение где находятся серверы, реализующие эти протоколы.

Аналогично тому, как коды США в США больше не используются для определения местоположения пользователя телефона, учитывая популярность переносимости номеров.

IP-адрес и другие методы, показанные выше, полезны для , предлагая значение по умолчанию , которое пользователь может настроить / исправить.

18 голосов
/ 04 августа 2008

Волшебство все, кажется, в

visitortime.getTimezoneOffset()

Это круто, я не знал об этом. Работает ли это в Internet Explorer и т. Д.? Оттуда вы сможете использовать JavaScript для Ajax, устанавливать куки, что угодно. Я бы, наверное, сам пошел по пути печенья.

Вам нужно будет разрешить пользователю изменять его. Мы пытались использовать геолокацию (через maxmind), чтобы сделать это некоторое время назад, и это было достаточно разумно неправильно - достаточно, чтобы этого не стоило делать, поэтому мы просто позволяем пользователю установить его в своем профиле и показываем уведомление пользователям, которые еще не установил их.

14 голосов
/ 30 августа 2008

Если вы используете OpenID для аутентификации, Простое расширение регистрации решит проблему для аутентифицированных пользователей (вам нужно будет преобразовать из tz в числовое).

Другим вариантом будет вывод часового пояса из предпочтения страны агента пользователя. Это довольно грубый метод (не подходит для en-US), но он хорошо подходит.

14 голосов
/ 25 мая 2010

Вот статья (с исходным кодом), в которой объясняется, как определять и использовать локализованное время в приложении ASP.NET (VB.NET, C #):

Время пришло

Короче говоря, описанный подход опирается на функцию JavaScript getTimezoneOffset, которая возвращает значение, которое сохраняется в файле cookie сеанса и используется программным кодом для настройки значений времени между GMT и местным временем. Приятно то, что пользователю не нужно указывать часовой пояс (код делает это автоматически). В этом участвует больше (поэтому я и делаю ссылку на статью), но предоставленный код делает его действительно простым в использовании. Я подозреваю, что вы можете преобразовать логику в PHP и другие языки (при условии, что вы понимаете ASP.NET).

11 голосов
/ 13 сентября 2016

Вы можете сделать это на клиенте с момент-часовой пояс и отправить значение на сервер; пример использования:

> moment.tz.guess()
"America/Asuncion"
11 голосов
/ 15 сентября 2014

Это просто с JavaScript и PHP:

Несмотря на то, что пользователь может связываться со своими внутренними часами и / или часовым поясом, лучший способ найти смещение до сих пор - new Date().getTimezoneOffset();. Он неинвазивен, не вызывает головных болей и избавляет от необходимости полагаться на третьих лиц.

Допустим, у меня есть таблица users, которая содержит поле date_created int(13) для хранения меток времени Unix;

Предполагая, что клиент creates a new account, данные принимаются post, и мне нужно insert/update date_created column с меткой времени клиента Unix, а не с сервера.

Поскольку 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

Теперь этот пример может соответствовать вашим потребностям, когда речь идет о вставке first отметки времени ... Когда речь идет о дополнительной отметке времени или таблице, вы можете рассмотреть возможность вставки значения tzo в таблицу users для будущая ссылка или установка в качестве сеанса или файла cookie.

P.S. НО что делать, если пользователь путешествует и переключает часовые пояса. Вход в GMT + 4, быстрое перемещение в GMT-1 и вход снова. Последний логин будет в будущем.

Я думаю ... мы слишком много думаем.

10 голосов
/ 01 декабря 2011

Простой способ сделать это с помощью:

new Date().getTimezoneOffset();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...