Сведения о вопросе

Martincow

16:03, 1st July, 2020

Теги

Определите timezone пользователя

Просмотров: 1058   Ответов: 24

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

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



  Сведения об ответе

DAAA

18:03, 1st July, 2020

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

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

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

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

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


  Сведения об ответе

$DOLLAR

18:03, 1st July, 2020

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

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


  Сведения об ответе

COOL

18:03, 1st July, 2020

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

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


  Сведения об ответе

darknet

18:03, 1st July, 2020

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

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


  Сведения об ответе

FAriza

18:03, 1st July, 2020

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

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

https://bitbucket.org/pellepim/jstimezonedetect


  Сведения об ответе

prince

18:03, 1st July, 2020

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

  1. Получить смещение timezone для пользователя
  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 (через обратный путь машины)


  Сведения об ответе

прога

18:03, 1st July, 2020

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

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

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

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

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

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

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

    И jsTimezoneDetect , и moment-timezone имеют эту функциональность.

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

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

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

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

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


  Сведения об ответе

DO__IT

18:03, 1st July, 2020

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

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

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

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


  Сведения об ответе

lesha

18:03, 1st July, 2020

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

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

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

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

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

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

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


  Сведения об ответе

dump

18:03, 1st July, 2020

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


  Сведения об ответе

appple

18:03, 1st July, 2020

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

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


  Сведения об ответе

ASER

18:03, 1st July, 2020

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 timestamp для этой функции; JavaScript уже знает timezone пользователя.

Подобный этому:

PHP:

echo '<script type="text/javascript">
var eltimio = maketimus('.$unix_timestamp_ofshiz.');
document.write(eltimio);
</script><noscript>pls enable javascript</noscript>';

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


  Сведения об ответе

VERSUION

18:03, 1st July, 2020

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

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


  Сведения об ответе

+-*/

18:03, 1st July, 2020

Кажется, все волшебство здесь.

visitortime.getTimezoneOffset()

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

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


  Сведения об ответе

davran

18:03, 1st July, 2020

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

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

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


  Сведения об ответе

appple

18:03, 1st July, 2020

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

Это как раз вовремя

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


  Сведения об ответе

lourence

18:03, 1st July, 2020

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

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


  Сведения об ответе

SKY

18:03, 1st July, 2020

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

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

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

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

Поскольку timezoneOffset необходим в момент insert/update,, он передается как дополнительный элемент $_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 можно преобразовать 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 timestamp... Когда речь заходит о дополнительном timestamp, или таблице, вы можете рассмотреть возможность вставки значения tzo в таблицу users для дальнейшего использования, или установить его как сеанс или как файл cookie.

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

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


  Сведения об ответе

прога

18:03, 1st July, 2020

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

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


  Сведения об ответе

DO__IT

18:03, 1st July, 2020

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

new Date().getTimezoneOffset();


  Сведения об ответе

LIZA

18:03, 1st July, 2020

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

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

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

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

  2. В PHP преобразуйте это смещение в допустимое имя timezone с помощью функции 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>
    

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


  Сведения об ответе

#hash

18:03, 1st July, 2020

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

<?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
?>


  Сведения об ответе

LAST

18:03, 1st July, 2020

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


  Сведения об ответе

lats

18:03, 1st July, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться