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

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

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

Ответы [ 24 ]

315 голосов
/ 27 ноября 2009
-new Date().getTimezoneOffset()/60;

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

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

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

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

190 голосов
/ 03 августа 2008

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

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

100 голосов
/ 01 августа 2008

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

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

53 голосов
/ 01 августа 2008

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

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

49 голосов
/ 07 августа 2012

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

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

https://bitbucket.org/pellepim/jstimezonedetect

39 голосов
/ 31 марта 2011

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

  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 (через устройство обратного хода)

33 голосов
/ 25 марта 2014

Во-первых, поймите, что обнаружение часового пояса в 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 объекта Date в течение нескольких различных моментов времени, используя результаты для выбора подходящего часового пояса. из внутреннего набора данных.

    Оба jsTimezoneDetect и момент-час имеют эту функцию.

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

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

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

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

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

29 голосов
/ 09 апреля 2011

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

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

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

Это будет читать сессионную переменную "time", которую мы сейчас собираемся создать.

На той же странице, в , вам необходимо прежде всего включить jQuery:

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

Также в , ниже 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) или любой другой часовой пояс, в котором вы находитесь.

23 голосов
/ 13 сентября 2012

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

23 голосов
/ 30 августа 2012

Я до сих пор не видел подробный ответ, который получает часовой пояс. Вам не нужно геокодировать по 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

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