Вопрос

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

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

Нет правильного решения

Другие советы

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

Метод getTimezoneOffset() вычтет ваше время из GMT и вернет количество минут.Итак, если вы живете в GMT-8, он вернет 480.

Чтобы перевести это в часы, разделите это число на 60.Кроме того, обратите внимание, что этот знак противоположен тому, что вам нужно: он рассчитывает смещение GMT ​​от вашего часового пояса, а не смещение вашего часового пояса от GMT.Чтобы это исправить, просто умножьте на -1.

Также обратите внимание, что w3school говорит:

Возвращенное значение не является постоянным, из -за практики использования времени сбережений дневного света.

Самый популярный (==стандартный?) способ определения часового пояса, который я видел, это просто спрашивая самих пользователей. Если ваш сайт требует подписки, это можно сохранить в данных профиля пользователя.Для анонимных пользователей даты могут отображаться в формате UTC, GMT или что-то в этом роде.

Я не пытаюсь быть умным придурком.Просто иногда некоторые проблемы имеют более тонкие решения вне контекста программирования.

На данный момент нет заголовков HTTP, которые сообщали бы часовой пояс клиентов, хотя было предложено включить его в спецификацию HTTP.

Если бы это был я, я бы, вероятно, попытался получить часовой пояс с помощью клиентского JavaScript, а затем отправить его на сервер с помощью Ajax или чего-то еще.

JavaScript — это самый простой способ получить местное время клиента.Я бы предложил использовать XMLHttpRequest чтобы отправить обратно местное время, а если это не удастся, вернуться к часовому поясу, определенному на основе их IP-адреса.

Что касается геолокации, я использовал МаксМинд ГеоIP в нескольких проектах, и это работает хорошо, хотя я не уверен, предоставляют ли они данные о часовом поясе.Вы платите за эту услугу, и они ежемесячно обновляют вашу базу данных.Они предоставляют оболочки на нескольких веб-языках.

Вот надежное решение JavaScript для определения часового пояса, в котором находится браузер.

>>> var timezone = jstz.determine();
>>> timezone.name(); 
"Europe/London"

https://bitbucket.org/pellepim/jstimezonedetect

Вот более полный способ.

  1. Получить смещение часового пояса для пользователя
  2. Проверьте несколько дней границы летнего времени, чтобы определить, находятся ли они в зоне, где используется летнее время.

Отрывок ниже:

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

Получение TZ и DST из JS (через Way Back Machine)

Во-первых, поймите, что определение часового пояса в JavaScript несовершенно.Вы можете получить местный смещение часового пояса для определенной даты и времени, используя getTimezoneOffset на примере Date объект, но это не совсем то же самое, что полный Часовой пояс IANA нравиться America/Los_Angeles.

Однако есть несколько вариантов, которые могут сработать:

  • Большинство современных браузеров поддерживают часовые пояса IANA при реализации API интернационализации ECMAScript, поэтому вы можете сделать это:

    const tzid = Intl.DateTimeFormat().resolvedOptions().timeZone;
    

    Результатом является строка, содержащая настройку часового пояса IANA компьютера, на котором выполняется код.

    Перечислены поддерживаемые среды в таблице международной совместимости.Развернуть DateTimeFormat раздел и посмотрите на функцию с именем resolvedOptions().timeZone defaults to the host environment.

    • Некоторые библиотеки, такие как Люксон используйте этот API для определения часового пояса с помощью таких функций, как luxon.Settings.defaultZoneName.
  • Если вам необходимо поддерживать более широкий набор сред, например старые веб-браузеры, вы можете использовать библиотеку для создания обоснованное предположение в часовом поясе.Они работают, сначала попробовав Intl API, если он доступен, а когда недоступен, они опрашивают getTimezoneOffset функция Date объекта для нескольких разных моментов времени, используя результаты для выбора подходящего часового пояса из внутреннего набора данных.

    Оба jsTimezoneDetect и момент-часовой пояс есть этот функционал.

    // using jsTimeZoneDetect
    var tzid = jstz.determine().name();
    
    // using moment-timezone
    var tzid = moment.tz.guess();
    

    В обоих случаях результат можно рассматривать только как предположение.Предположение может быть верным во многих случаях, но не во всех.

    Кроме того, эти библиотеки необходимо периодически обновлять, чтобы противодействовать тому факту, что многие старые реализации JavaScript знают только о текущий правило перехода на летнее время для своего местного часового пояса. Подробнее об этом здесь.

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

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

Используя подход Unkwntech, я написал функцию с использованием jQuery и PHP.Это проверено и работает!

На странице PHP, где вы хотите использовать часовой пояс в качестве переменной, поместите этот фрагмент кода где-нибудь в верхней части страницы:

<?php
    session_start();
    $timezone = $_SESSION['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.Ну, это просто:(создайте новый файл с именем часовой пояс.php и укажите на него с помощью URL-адреса выше)

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

Если это работает правильно, сначала загрузится страница, выполнится JavaScript и перезагрузится страница.После этого вы сможете прочитать переменную $timezone и использовать ее в свое удовольствие!Он возвращает текущее смещение часового пояса UTC/GMT (GMT -7) или любого часового пояса, в котором вы находитесь.

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

Во-первых, часовой пояс — это не просто смещение от GMT.Это территория, на которой правила времени установлены местными стандартами.В некоторых странах действует летнее время, и летнее время включается в разное время.Обычно важно получить фактическую зону, а не только текущее смещение.

Если вы собираетесь сохранить этот часовой пояс, например, в настройках пользователя вам нужен пояс, а не только смещение.Для конверсий в реальном времени это не будет иметь большого значения.

Теперь, чтобы получить часовой пояс с помощью JavaScript, вы можете использовать это:

>> new Date().toTimeString();
"15:46:04 GMT+1200 (New Zealand Standard Time)"
//Use some regular expression to extract the time.

Однако мне было проще просто использовать этот надежный плагин, который возвращает часовой пояс в формате Олсена:

https://github.com/scottwater/jquery.detect_timezone

Чтобы отправить смещение часового пояса в качестве заголовка HTTP в запросах AJAX с помощью jQuery

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        xhr.setRequestHeader("X-TZ-Offset", -new Date().getTimezoneOffset()/60);
    }
});

Вы также можете сделать что-то подобное, чтобы получить фактическое имя часового пояса, используя moment.tz.guess(); от http://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

С помощью 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();
?>

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

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

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

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()

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

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

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

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

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

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

Другой вариант — определить часовой пояс на основе предпочтений страны пользовательского агента.Это несколько грубый метод (не работает в США), но он дает хорошее приближение.

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

Пора

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

С 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 = // Get from the database
$created = date("F j, Y, g:i a",$date_created); // Return it to the user or whatever

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

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

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

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

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

Простой способ сделать это — использовать:

new Date().getTimezoneOffset();

Получение действительного имени часового пояса базы данных TZ в PHP представляет собой двухэтапный процесс:

  1. С помощью JavaScript получите смещение часового пояса за считанные минуты. getTimezoneOffset.Это смещение будет положительным, если местный часовой пояс отстает от UTC, и отрицательным, если он опережает UTC.Поэтому вы должны добавить противоположный знак к смещению.

    var timezone_offset_minutes = new Date().getTimezoneOffset();
    timezone_offset_minutes = timezone_offset_minutes == 0 ? 0 : -timezone_offset_minutes;
    

    Передайте это смещение в PHP.

  2. В PHP преобразуйте это смещение в допустимое имя часового пояса с помощью timezone_name_from_abbr функция.

    // Just an example.
    $timezone_offset_minutes = -360;  // $_GET['timezone_offset_minutes']
    
    // Convert minutes to seconds
    $timezone_name = timezone_name_from_abbr("", $timezone_offset_minutes*60, false);
    
    // America/Chicago
    echo $timezone_name;</code></pre>
    

Я написал об этом сообщение в блоге: Как определить часовой пояс пользователя в PHP.Он также содержит демо-версию.

Одним из возможных вариантов является использование Date поле заголовка, которое определено в RFC 7231 и должен включать часовой пояс.Конечно, не гарантируется, что значение действительно соответствует часовому поясу клиента, но оно может быть удобной отправной точкой.

Вот как я это делаю.Это установит часовой пояс PHP по умолчанию в соответствии с локальным часовым поясом пользователя.Просто вставьте следующее вверху всех страниц:

<?php
session_start();

if(!isset($_SESSION['timezone']))
{
    if(!isset($_REQUEST['offset']))
    {
    ?>
        <script>
        var d = new Date()
        var offset= -d.getTimezoneOffset()/60;
        location.href = "<?php echo $_SERVER['PHP_SELF']; ?>?offset="+offset;
        </script>
        <?php   
    }
    else
    {
        $zonelist = array('Kwajalein' => -12.00, 'Pacific/Midway' => -11.00, 'Pacific/Honolulu' => -10.00, 'America/Anchorage' => -9.00, 'America/Los_Angeles' => -8.00, 'America/Denver' => -7.00, 'America/Tegucigalpa' => -6.00, 'America/New_York' => -5.00, 'America/Caracas' => -4.30, 'America/Halifax' => -4.00, 'America/St_Johns' => -3.30, 'America/Argentina/Buenos_Aires' => -3.00, 'America/Sao_Paulo' => -3.00, 'Atlantic/South_Georgia' => -2.00, 'Atlantic/Azores' => -1.00, 'Europe/Dublin' => 0, 'Europe/Belgrade' => 1.00, 'Europe/Minsk' => 2.00, 'Asia/Kuwait' => 3.00, 'Asia/Tehran' => 3.30, 'Asia/Muscat' => 4.00, 'Asia/Yekaterinburg' => 5.00, 'Asia/Kolkata' => 5.30, 'Asia/Katmandu' => 5.45, 'Asia/Dhaka' => 6.00, 'Asia/Rangoon' => 6.30, 'Asia/Krasnoyarsk' => 7.00, 'Asia/Brunei' => 8.00, 'Asia/Seoul' => 9.00, 'Australia/Darwin' => 9.30, 'Australia/Canberra' => 10.00, 'Asia/Magadan' => 11.00, 'Pacific/Fiji' => 12.00, 'Pacific/Tongatapu' => 13.00);
        $index = array_keys($zonelist, $_REQUEST['offset']);
        $_SESSION['timezone'] = $index[0];
    }
}

date_default_timezone_set($_SESSION['timezone']);

//rest of your code goes here
?>

Попробуйте этот PHP-код:

<?php
    $ip = $_SERVER['REMOTE_ADDR'];
    $json = file_get_contents("http://api.easyjquery.com/ips/?ip=" . $ip . "&full=true");
    $json = json_decode($json,true);
    $timezone = $json['LocalTimeZone'];
?>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top