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

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

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

1.08.2008 00:42:38
Спросите пользователя. Если вы получаете часовой пояс с компьютера пользователя, и он установлен неправильно, то что?
Rob Williams 2.12.2008 00:51:27
Тогда пользователю, наверное, все равно?
agnoster 11.11.2010 08:48:18
Вы имеете в виду stackoverflow.com/q/1091372/218196 ?
Felix Kling 24.03.2014 18:50:27
К сожалению, ответы на этот вопрос также позволяют для профилирования пользователей и геозон.
William Entriken 24.09.2018 23:41:50
Зачем вам нужно знать часовой пояс пользователя?
Braiam 5.10.2018 15:15:49
24 ОТВЕТА
-new Date().getTimezoneOffset()/60;

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

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

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

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

323
30.05.2018 15:56:46
А как насчет пользователей, которые используют сотовые телефоны с браузерами без поддержки JavaScript? Мне нравится вопрос, пользователь спрашивает о заголовках HTTP, пользовательском агенте ... есть ли способ сделать эту работу на стороне сервера максимально точной?
Nischal 9.09.2011 14:57:20
Это не всегда работает для DST. Получить смещение часового пояса делает именно то, что он говорит. Это смещение. Часовая зона на самом деле географическая зона. Это не сработает для перехода на летнее время, поскольку вы не знаете, в каком полушарии живет пользователь, или если в его стране даже есть летнее время. Почему бы не использовать это вместо:>>> date.toTimeString() "15:46:04 GMT+1200 (New Zealand Standard Time)"
Keyo 30.08.2012 03:49:28
Я позволю себе не согласиться с Кейо. Определение getTimezoneOffset () (согласно стандарту ECMA ecma-international.org/ecma-262/5.1/#sec-15.9.5.26 ) «Возвращает разницу между местным временем и временем UTC в минутах». - другими словами, необходимо учитывать летнее время. Документация Mozilla гласит: «Летнее время не позволяет этому значению быть постоянным даже для данной локали».
xgretsch 6.12.2013 11:24:45
@xgretsch: получает текущее смещение пользователя от GMT. Это хорошо, если вы представляете другое время, которое происходит в тот же день (если текущая дата не является датой перехода, где это может быть неправильно). Однако есть много часовых поясов, которые имеют одинаковое смещение от GMT, и они могут иметь разные даты переключения или не использовать переход на летнее время.
Mike Dimmick 7.04.2014 17:21:46
Здесь нужно отметить одну вещь; в некоторых местах (например, в Ньюфаундленде в Канаде) часовые пояса отключены на полчаса, поэтому после деления на 60 ваш ответ может не быть целым числом.
Jason Walton 30.07.2014 19:30:56

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

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

192
10.09.2013 11:42:53
Как насчет того, когда пользователь загружает файл .ics, который должен иметь время начала, определенное для его местоположения (например, 9-11 утра по всей стране)? Они не должны сказать, какой у них часовой пояс.
Marcy Sutton 27.01.2011 21:57:48
@Ishmaeel: но пользователи путешествуют по всему миру, и им не нужно указывать свой часовой пояс каждый раз, когда они входят в какой-то не родной часовой пояс
Rajat Gupta 22.07.2011 08:04:51
Это не отвечает на вопрос, который явно подразумевает, что он ищет технологическое решение.
G-Wiz 9.08.2011 20:20:40
@gWiz OP просит стандартное решение. Это довольно стандартно.
Simon Bergot 6.04.2012 10:26:25
Наилучшим решением, вероятно, будет сочетание запроса пользователя (например, предоставление раскрывающегося списка часовых поясов в верхней части отчета), при этом по умолчанию выбранный раскрывающийся список выбирает часовой пояс, определенный пользователем, когда пользователь находится на мобильном телефоне. устройство, которое предоставляет информацию о местоположении, и по умолчанию UTC.
Triynko 10.02.2015 20:30:25

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

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

126
1.08.2008 12:19:17
Как ни странно, это единственный правильный ответ на вопрос, который спрашивает, как это сделать на стороне сервера. Я подозреваю, что причина в том, что есть другие ответы с большим количеством голосов, состоит в том, что как только вы понимаете, что вам нужно сделать это на стороне клиента, вы в конечном итоге используете другие ответы. Но ИМХО любой, кто голосует против другого ответа, должен также проголосовать против этого.
TTT 18.02.2016 22:32:47
Я считаю, что лучший способ - использовать гео-ip местоположение для сортировки возможных часовых поясов и по умолчанию выбрать первый, который (близко) соответствует временному смещению агента пользователя (требуется JavaScript). Даже после этого вы должны предоставить способ исправить часовой пояс после того, как даже этот метод выберет неправильный.
Mikko Rantalainen 16.02.2017 10:47:21
@MikkoRantalainen осторожен при использовании прокси через, поскольку они не всегда рекламируют себя в заголовках.
Matthieu 17.05.2017 16:31:36
@Matthieu, в настоящее время существует лучший ответ: stackoverflow.com/a/11836123/334451
Mikko Rantalainen 18.05.2017 11:30:51
Это буквально единственный ответ, который фактически ответил на поставленный вопрос.
lscoughlin 24.04.2019 09:42:16

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

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

54
13.10.2018 13:07:16
Я проголосовал за этот ответ, потому что широта и долгота, полученные из баз данных, таких как GeoIP (у которых есть бесплатная версия на данный момент), могут быть объединены с базами данных, которые преобразуют такую ​​координату в часовой пояс. Я думаю, что у GeoNames есть последняя такая база данных.
Peter O. 20.11.2011 06:52:34
Текущие версии (как платные, так и бесплатные) баз данных / API MaxMind GeoIP действительно предоставляют информацию о часовом поясе (для моего часового пояса возвращается «Европа / Лондон»). Я не могу вспомнить, была ли старая версия их системы GeoIP сделал то же самое, но теперь это работает очень хорошо! Поля MaxMind называются «time_zone», «time_zone_name».
Matthew Slyman 23.12.2015 21:26:42

Во-первых, следует понимать, что обнаружение часового пояса в 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.
  • Если вам требуется поддержка более широкого набора сред, таких как старые веб-браузеры, вы можете использовать библиотеку, чтобы сделать обоснованное предположение о часовом поясе. Они работают, сначала пробуя IntlAPI, если он доступен, а когда он недоступен, они запрашивают getTimezoneOffsetфункцию Dateобъекта в течение нескольких различных моментов времени, используя результаты для выбора подходящего часового пояса из внутреннего набора данных.

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

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

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

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

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

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

49
25.02.2019 18:10:55
Использование географического местоположения пользователя (то есть его языка) для определения часового пояса также имеет недостатки. Пользователи могут захотеть использовать определенный часовой пояс на своем устройстве, который не является локальным часовым поясом, даже если он будет отображаться одновременно (или нет). Например, путешественники часто оставляют свои устройства с часовым поясом, установленным в их обычном месте, и не ожидают, что даты и время будут использовать другое смещение без уведомления. Я мог бы говорить из личного опыта здесь… ;-)
RobG 16.08.2019 01:07:08
Не могу сказать, троллишь ли ты меня, Роб. ;) Но ни один из этих подходов не использует их локаль, а скорее настройку на устройстве, поэтому выровнен с вашей точкой. (Только альтернативный подход, упомянутый в последнем абзаце, будет использовать текущее местоположение.)
Matt Johnson-Pint 16.08.2019 16:07:00
Включение с примечанием терминологии: «языковой стандарт» категорически не географическое местоположение пользователя. «Языковой стандарт» - это группа параметров, таких как язык, формат чисел, календарь и т. Д. Например, языковой стандарт de_DE указывает немецкий язык в качестве языка по умолчанию, евро в качестве валюты по умолчанию, запятые в качестве десятичного разделителя, точки в качестве разделителя тысяч и григорианский как календарь. См developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
azernik 25.02.2020 04:01:43

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

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

https://bitbucket.org/pellepim/jstimezonedetect

Приложение 1: Сейчас этот проект находится на GitHub: https://github.com/pellepim/jstimezonedetect

49
24.03.2020 15:39:24
Ответы, содержащие только ссылки, не приветствуются, потому что, если ссылка исчезает, ответ перестает быть полезным; и потому что, не переходя по ссылке, читатели не знают, дает ли она хороший ответ. В этом случае вы могли бы уточнить, что это сторонняя библиотека, которая использует основанный на базе данных подход к идентификации, и, возможно, объяснить некоторые принципы ее работы.
IMSoP 2.02.2015 17:32:27
Это! Это путь. Простая библиотека, правильно обрабатывает DST. Другие ответы полны WTF, и многие не делают DST.
Dirbaio 1.11.2016 01:34:13
Эта библиотека очень умная. Он работает, запрашивая текущее смещение в UTC, затем корректируя время объекта JavaScript Date, добавляя или вычитая секунды, пока смещение к UTC не изменится. Используя этот метод, эта библиотека вычисляет достаточно изменений DST, чтобы однозначно идентифицировать часовой пояс. Я думаю, что библиотека могла бы иметь даже лучшую производительность, если бы она выполняла бинарный поиск вместо линейного поиска. Возвращаемым значением является информационный ключ зоны IANA (он же база данных часовых поясов Олсона).
Mikko Rantalainen 18.05.2017 11:25:03
Эта библиотека больше не нужна. Современные браузеры поддерживают API-интерфейс Intl, который возвращает строку часового пояса IANA. Смотрите этот ответ .
Dan Dascalescu 17.03.2019 05:41:11

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

  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)

42
13.10.2018 13:15:17
Это сработало для меня! Прочитайте комментарии под сообщением в блоге для пары обновлений кода.
arlomedia 15.04.2012 19:35:14
Это по-прежнему будет возвращать только стандартное смещение для часового пояса, например +02: 00. Он не даст вам достаточно информации для определения часового пояса пользователя, например Africa/Johannesburgили Europe/Istanbul. Смотрите тег часового пояса вики .
Matt Johnson-Pint 12.07.2014 22:52:45

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

32
13.10.2018 13:19:04
мне это нравится, но у меня может быть что-то, что проверяет текущую переменную $ _SESSION ['time'] и заставляет javascript перезагружаться, только если он другой
Christopher Chase 15.09.2011 04:59:39
Вероятно, проще использовать Cookie, чем Session, чтобы транспортировать это, поскольку блокировка и десериализация сеанса PHP может вызвать замедление работы вашего приложения. Для максимальной эффективности вы можете скопировать значение в сеанс и удалить cookie, чтобы он не отправлялся в последующих запросах.
IMSoP 2.02.2015 17:34:25

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

25
27.03.2017 18:08:32
Это только возвращает текущее смещение часового пояса - не часовой пояс . Смотрите тег часового пояса вики .
Matt Johnson-Pint 12.07.2014 22:47:21
Отредактировано, чтобы включить информацию о том, как сделать то же самое для названия часового пояса.
philfreo 27.03.2017 18:08:44

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

24
30.08.2012 05:18:17

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

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

22
13.10.2018 13:13:32

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

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

21
13.10.2018 13:21:37
$ unix_timestamp_ofshiz? Здесь чего-то не хватает и это не совсем работает, хотя кажется, что это может быть хорошим ответом.
user6173198 15.09.2016 05:09:24

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

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

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

21
13.10.2018 13:27:30

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

-new Date().getTimezoneOffset()/60;
20
20.02.2013 16:27:10
Это функция Javascript, а не функция PHP.
cincodenada 16.02.2013 01:05:14
Кроме того, он возвращает только текущее смещение часового пояса, а не часовой пояс . Смотрите тег часового пояса вики .
Matt Johnson-Pint 12.07.2014 22:45:57
Это просто копия принятого ответа, почему вы даже голосуете за него.
Rambatino 12.10.2018 21:59:49

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

visitortime.getTimezoneOffset()

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

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

19
13.10.2018 13:09:21

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

Пора

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

15
31.07.2017 11:30:41
Ссылка мертва. Я думаю, что это альтернативная ссылка: devproconnections.com/article/aspnet2/it-s-about-time-122778
Gan 21.03.2013 03:56:22
Статья также доступна в формате PDF здесь: app.box.com/shared/bfvvmidtyg
Ivaylo Slavov 7.10.2013 08:41:27
Описанный в этой статье метод преобразования времени сервера UTC в время локального клиента неверен. Использование текущего клиентского смещения для настройки времени UTC на сервере приведет к неправильному «локальному» времени на пол года для клиентских локалей, которые отмечают переход на летнее время. Рассмотрим следующий сценарий: клиент в Великобритании 14 января 2013 года (GMT + 0000 по стандартному времени) устанавливает дату и время 21 августа 2015 года в 14:00 (GMT + 0100 летнее время). Это нормализуется на сервере до 21 августа 2015 года 13:00 UTC. В день, когда это происходит, смещение клиента равно 0, поэтому время, отправленное обратно клиенту, будет 21 августа 2015 года, 13:00.
Stephen Blair 23.01.2015 17:25:11
Допустимый момент, но я не утверждал, что это пуленепробиваемое решение. Если вам нужно внедрить действительно чувствительное ко времени решение, скажем, приложение для бронирования билетов на поезд, вам нужно найти более полное (и комплексное решение). Однако для многих приложений это не будет проблемой. Потому что во многих случаях мы хотим локализовать значения GMT для текущего сеанса. Теперь, если у вас есть приложение, которому нужно сохранить временную метку для некоторых даже в будущем, и оно не может переносить DTS, то правильным способом было бы предоставить опцию для экономии времени непосредственно в GMT. Если вы знаете лучший вариант, пожалуйста, поделитесь.
Alek Davis 24.01.2015 00:25:05

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

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

14
2.09.2008 15:14:02

Это просто с 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 и вход снова. Последний логин будет в будущем.

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

13
13.10.2018 13:30:39

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

> moment.tz.guess()
"America/Asuncion"
13
13.10.2018 13:31:13
Название функции говорит все о ее точности ;-)
Legends 7.11.2017 22:37:37
В настоящее время, moment.js я больше не рекомендую. Есть намного меньшие альтернативы в настоящее время ( dayjs , date-fns ). Момент огромен .
Dan Dascalescu 17.03.2019 05:45:21

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

11
13.10.2018 13:34:35
Я думаю, что более простой процесс - позвонить Intl.DateTimeFormat().resolvedOptions().timeZoneи отправить его на веб-сервер. Ссылка: stackoverflow.com/questions/9772955/…
Michael Tsang 20.02.2019 04:56:23

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

new Date().getTimezoneOffset();
9
14.10.2012 12:10:04
Почему вы перепечатали идентичный ответ (от Джона Айзекса) от 2 лет назад: stackoverflow.com/a/1809974/836407 ?
chown 30.01.2012 01:01:22
Кроме того, он возвращает только текущее смещение часового пояса, а не часовой пояс . Смотрите тег часового пояса вики .
Matt Johnson-Pint 12.07.2014 22:46:19

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

8
8.09.2014 23:25:56
К сожалению, этот заголовок, по-видимому, в основном предназначен для ответов, а не для запросов: «Пользовательский агент МОЖЕТ отправлять поле заголовка Date в запросе, хотя, как правило, не делает этого, если не считается, что он передает полезную информацию на сервер». Я только что проверил, и Firefox не отправляет его.
IMSoP 2.02.2015 17:43:50

Вот как я это делаю. Это установит часовой пояс 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
?>
8
7.02.2016 00:23:37
Это не учитывает настройки перехода на летнее время - пользователь в Дублине будет соответствовать вашему «Европа / Дублин» зимой, но «Европа / Белград» летом. Если вы собираетесь использовать текущее смещение, все, что вы можете разумно предположить, это смещение, а не географический идентификатор.
IMSoP 2.02.2015 17:40:20

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