Определить часовой пояс пользователя

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

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

Ответ 1

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

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

https://bitbucket.org/pellepim/jstimezonedetect

Ответ 6

Вот более полный путь.

  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)

Ответ 7

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

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

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

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

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

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

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

    Как jsTimezoneDetect, так и момент-время имеют эту функциональность.

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

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

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

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

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

Ответ 8

Используя подход 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. Ну, это просто так: (создайте новый файл с именем timezone.php и укажите на него указанным выше URL)

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

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

Ответ 9

Чтобы отправить смещение часового пояса как 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/

Ответ 10

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

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

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

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

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

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

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

Ответ 11

С помощью функции date 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();
?>

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

Ответ 12

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

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

Ответ 13

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

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

Ответ 14

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

visitortime.getTimezoneOffset()

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

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

Ответ 15

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

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

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

Ответ 17

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

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

Ответ 18

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

Это о времени

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

Ответ 19

Это просто с 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 в таблицу пользователей для дальнейшего использования или настройки это как сессия или как cookie.

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

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

Ответ 20

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

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

Ответ 21

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

new Date().getTimezoneOffset();

Ответ 22

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

  1. С помощью JavaScript получите смещение часового пояса в минутах через getTimezoneOffset. Это смещение будет положительным, если локальный часовой пояс отстает от 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. Он также содержит демо.

Ответ 23

Вот как я это делаю. Это установит часовой пояс 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
?>

Ответ 24

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

Ответ 25

Попробуйте этот код 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'];
?>