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

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

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

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

Rob Williams 02.12.2008 03:51

Тогда пользователю, наверное, все равно?

agnoster 11.11.2010 11:48

Вы имеете в виду stackoverflow.com/q/1091372/218196?

Felix Kling 24.03.2014 22:50

Нет. Не помогает моему текущему делу, хотя выглядит полезным для других вещей. Что мне нужно сделать, так это взять минуты getTimezoneOffset() и передать их чему-то, что даст мне, например, America/Los_Angeles. Или передайте что-нибудь функции, которая даст мне это, или эквивалент. Я не хочу отображать время, основанное на часовом поясе, установленном пользователями, больше, чем на том месте, где что-то произошло.

chris 24.03.2014 23:00

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

Felix Kling 25.03.2014 03:10

К сожалению, ответы на этот вопрос также позволяют профилировать пользователей и выполнять геозону.

William Entriken 25.09.2018 02:41

Зачем нужно знать часовой пояс пользователя?

Braiam 05.10.2018 18:15

Что ж, к счастью для вас, этот ответ можно найти на нашем собственном веб-сайте stackoverflow: stackoverflow.com/questions/1033/ip-to-country, спойлер: hostip.info/use.html

sven 04.08.2008 15:11

Я не думаю, что это возможно, если пользователь не отправит информацию на сервер. Это должно выполняться на стороне клиента.

Michael Tsang 20.02.2019 07:53
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
643
9
219 885
25

Ответы 25

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

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

Как ни странно, это единственный ответ правильный на вопрос, который спрашивает, как это сделать на стороне сервера. Я подозреваю, что есть другие ответы с большим количеством голосов, потому что, как только вы понимаете, что вам нужно сделать это на стороне клиента, вы в конечном итоге используете другие ответы. Но ИМХО, любой, кто голосует за другой ответ, должен голосовать и за этот.

TTT 19.02.2016 01:32

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

Mikko Rantalainen 16.02.2017 13:47

@MikkoRantalainen осторожно использует прокси-серверы, так как они не всегда рекламируют себя в заголовках.

Matthieu 17.05.2017 19:31

@Matthieu, в настоящее время существует лучший ответ: stackoverflow.com/a/11836123/334451

Mikko Rantalainen 18.05.2017 14:30

Это буквально единственный ответ, который действительно отвечал на поставленный вопрос.

lscoughlin 24.04.2019 12:42

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

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

Я проголосовал за этот ответ, потому что широта и долгота, полученные из таких баз данных, как GeoIP (у которых есть бесплатная версия, доступная на данный момент), могут быть объединены с базами данных, которые преобразуют такие координаты в часовой пояс. Я думаю, что у GeoNames есть последняя такая база данных.

Peter O. 20.11.2011 10:52

Текущие версии (как бесплатные, так и платные) баз данных / API MaxMind GeoIP действительно предоставляют информацию о часовом поясе (он возвращает «Европа / Лондон» для моего часового пояса.) Я не могу вспомнить, была ли старая версия их системы GeoIP сделал то же самое, но теперь он работает очень хорошо! Поля MaxMind называются «time_zone», «time_zone_name».

Matthew Slyman 24.12.2015 00:26

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

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

А как насчет того, когда пользователь загружает файл .ics, время начала которого должно соответствовать его местоположению (например, 9-11 утра по всей стране)? Им НЕ ДОЛЖНО говорить, какой у них часовой пояс imo.

Marcy Sutton 28.01.2011 00:57

Почему бы не принять это как правильный ответ? Ответ, данный Unkwntech, не работает даже для браузеров, отличных от IE.

Xiè Jìléi 18.02.2011 04:33

@Ishmaeel: но пользователи путешествуют по всему миру, и им не нужно указывать свой часовой пояс каждый раз, когда они входят в систему из какого-то другого часового пояса

Rajat Gupta 22.07.2011 12:04

Это не отвечает на вопрос, что явно подразумевает, что он ищет технологическое решение.

G-Wiz 10.08.2011 00:20

@gWiz OP просит стандартное решение. Это довольно стандартно.

Simon Bergot 06.04.2012 14:26

Лучшим решением, вероятно, будет комбинация запроса пользователя (например, предоставление раскрывающегося списка часового пояса в верхней части отчета), при одновременном выборе по умолчанию раскрывающегося выбора часового пояса, определенного GPS, когда пользователь находится на мобильном телефоне. устройство, которое предоставляет информацию о местоположении, и в противном случае по умолчанию используется UTC.

Triynko 10.02.2015 23:30

@ user01 Вы не можете сделать такое общее заявление и считаете его правильным для всех ситуаций. Достаточно приложений с профилем пользователя, куда пользователь не ездит каждый день. Таким образом, выпадающий список с часовыми поясами подходит для "большинства" пользовательских требований.

Pascal 28.08.2016 12:38

Кажется, вся магия в

visitortime.getTimezoneOffset()

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

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

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

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

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

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

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

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

The returned value is not a constant, because of the practice of using Daylight Saving Time.

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

bimbom22 28.06.2010 23:54

@jordanstephens Я не эксперт, поэтому не знаю, есть ли обстоятельства, при которых это не сработает, но у меня это сработало.

JD Isaacks 29.06.2010 00:00

А как насчет пользователей сотовых телефонов с браузерами без поддержки javascript? Мне нравится вопрос, когда пользователь спрашивает о HTTP-заголовках, пользовательском агенте ... есть ли способ сделать эту работу на стороне сервера как можно более точной?

Nischal 09.09.2011 18:57

Это странно. Для меня это возвращает -4, но я нахожусь в GET, который должен быть +4 - что мне не хватает? Я проверил, что в моей ОС установлен правильный часовой пояс.

hippietrail 17.01.2012 18:12

getTimezoneOffset () возвращает количество минут при вычитании текущего времени из времени GMT. Итак, если вы живете в Калифорнии, это PST, то есть GMT-8, так что вы отстаете на 8 часов. Вычтите это из GMT с помощью getTimezoneOffset (), и он вернет 480 минут. Если вы хотите найти свое смещение, умножьте его на -1 и разделите на 60.

NudeCanalTroll 30.01.2012 03:30

Это не учитывает переход на летнее и летнее время, но ссылка, опубликованная Джозефом Ластом, учитывает: stackoverflow.com/a/5492192/462162

arlomedia 15.04.2012 23:36

Это не всегда работает для летнего времени. Get timezone offset делает именно то, что написано. Это смещение. ЧАСОВАЯ ЗОНА - это фактически географическая область. Это не сработает для летнего времени, поскольку вы не знаете, в каком полушарии живет пользователь или есть ли в их стране летнее время. Почему бы вместо этого не использовать это: >>> date.toTimeString() "15:46:04 GMT+1200 (New Zealand Standard Time)"

Keyo 30.08.2012 07:49

Я прошу не согласиться с Кейо. Определение getTimezoneOffset () (согласно стандарту ECMA ecma-international.org/ecma-262/5.1/#sec-15.9.5.26): «Возвращает разницу между местным временем и временем UTC в минутах». - другими словами, следует учитывать переход на летнее время. В документации Mozilla говорится: «Переход на летнее время не позволяет этому значению быть постоянным даже для данной локали».

xgretsch 06.12.2013 15:24

@xgretsch: получает смещение Текущий пользователя от GMT. Это нормально, если вы представляете другое время, которое происходит в тот же день (если текущая дата не является датой перехода, где это может быть неверно). Однако есть много часовых поясов, которые имеют одинаковое смещение от GMT, и они могут иметь разные даты перехода или не использовать летнее время.

Mike Dimmick 07.04.2014 21:21

@Keyo: вывод toTimeString зависит от реализации: ecma-international.org/ecma-262/5.1/#sec-15.9.5.4. Нет гарантии, что он будет включать название часового пояса. Также нет гарантии, что, если он делает включает имя часового пояса, он сопоставляется со всем, о чем сервер знает. Иногда он может работать в некоторых браузерах, но я бы не хотел на него полагаться.

Mike Dimmick 07.04.2014 21:29

@Mike Dimmick: Хотя это правда, сам вопрос спрашивает, есть ли способ получить смещение часового пояса, а не сам фактический часовой пояс, так что это должно быть правильно.

sovemp 08.04.2014 01:16

@Mike Dimmick: Ах, я понимаю вашу точку зрения. Я полагаю, что нет простого ответа на вопрос «каково смещение часового пояса пользователя» - вам нужно спросить «каково смещение часового пояса пользователя в определенный момент времени». Я начинаю думать, что единственный надежный способ сделать это - одно из тех ужасных решений, когда вы устанавливаете часовой пояс, распечатываете время по местному времени и сравниваете то, что у вас есть!

xgretsch 09.04.2014 00:27

Здесь следует отметить одну вещь; в некоторых местах (например, в Ньюфаундленде в Канаде) часовые пояса отличаются на полчаса, так что после деления на 60 ваш ответ может быть не целым числом.

Jason Walton 30.07.2014 23:30

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

ingredient_15939 03.01.2015 12:16

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

Triynko 10.02.2015 23:24

Вопрос спрашивает, как это определить на стороне сервера. Это код для клиента.

Rob 17.06.2016 05:45
w3scool says The returned value is not a constant, because of the practice of using Daylight Saving Time. as a Note.
Kishor Pawar 06.10.2016 14:01

Это даже не НАЧАЛО ответа на вопрос.

lscoughlin 24.04.2019 12:41

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

Пора

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

Ссылка мертвая. Думаю, это альтернативная ссылка: devproconnections.com/article/aspnet2/it-s-about-time-122778

Gan 21.03.2013 07:56

Статья также доступна в формате PDF здесь: app.box.com/shared/bfvvmidtyg

Ivaylo Slavov 07.10.2013 12:41

Метод преобразования времени сервера 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 20:25

Верно, но я не утверждал, что это пуленепробиваемое решение. Если вам нужно внедрить действительно чувствительное ко времени решение, например приложение для бронирования билетов на поезд, то вам нужно найти более полное (и комплексное) решение. Однако для многих приложений это не будет проблемой. Потому что во многих случаях мы хотим локализовать значения GMT для текущего сеанса. Теперь, если у вас есть приложение, которому необходимо сохранять временную метку для некоторых даже в будущем, и оно не может поддерживать DTS, тогда правильным способом будет предоставить возможность экономии времени непосредственно в GMT. Если знаете вариант получше, поделитесь, пожалуйста.

Alek Davis 24.01.2015 03:25

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

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

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

  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)

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

arlomedia 15.04.2012 23:35

Это по-прежнему будет возвращать только стандартное смещение для часового пояса, например +02: 00. Он не даст вам достаточно информации, чтобы определить часовой пояс пользователя, такого как Africa/Johannesburg или Europe/Istanbul. См. вики по тегу часового пояса.

Matt Johnson-Pint 13.07.2014 02:52

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

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

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

Будет прочитана переменная сеанса «время», которую мы сейчас создаем.

На той же странице в

, you need to first of all include jQuery:
<script type = "text/javascript" src = "http://code.jquery.com/jquery-latest.min.js"></script>

Также в

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

мне это нравится, но у меня может быть что-то, что проверяет текущий $ _SESSION ['time'] и заставляет javascript перезагружаться только в том случае, если он отличается

Christopher Chase 15.09.2011 08:59

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

IMSoP 02.02.2015 20:34

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

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

$ unix_timestamp_ofshiz? Здесь чего-то не хватает и что-то не работает, хотя кажется, что это может быть хорошим ответом.

user6173198 15.09.2016 08:09

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

new Date().getTimezoneOffset();

Почему вы репостили идентичный ответ (от Джона Исаакса) 2 года назад: stackoverflow.com/a/1809974/836407?

chown 30.01.2012 05:01

Кроме того, он возвращает только смещение часового пояса Текущий, но не часовой пояс. См. вики по тегу часового пояса.

Matt Johnson-Pint 13.07.2014 02:46

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

Это не учитывает корректировки "летнего времени" - пользователь в Дублине будет соответствовать вашему "Европа / Дублин" зимой, но "Европа / Белград" летом. Если вы собираетесь использовать текущее смещение, все, что вы можете разумно предположить, - это смещение, а не географический идентификатор.

IMSoP 02.02.2015 20:40

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

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

Кроме того, он возвращает только смещение часового пояса Текущий, но не часовой пояс. См. вики по тегу часового пояса.

Matt Johnson-Pint 13.07.2014 02:45

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

Rambatino 13.10.2018 00:59

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

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

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

https://github.com/pellepim/jstimezonedetect

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

IMSoP 02.02.2015 20:32

Этот! Это путь. Простая библиотека, правильно обрабатывает DST. Другие ответы полны WTF, и многие не используют DST.

Dirbaio 01.11.2016 04:34

Эта библиотека очень умная. Он работает, запрашивая текущее смещение к UTC, затем корректируя время объекта JavaScript Date, добавляя или вычитая секунды до тех пор, пока смещение к UTC не изменится. Используя этот метод, эта библиотека определяет достаточно много изменений DST, чтобы однозначно определить часовой пояс. Я думаю, что библиотека могла бы иметь еще лучшую производительность, если бы выполняла двоичный поиск вместо линейного. Возвращаемое значение - это информационный ключ зоны IANA (также известный как база данных часовых поясов Олсона).

Mikko Rantalainen 18.05.2017 14:25

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

Dan Dascalescu 17.03.2019 08:41

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

Во-первых, часовой пояс - это не просто смещение от 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

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

Это возвращает только смещение часового пояса Текущий, но не часовой пояс. См. вики по тегу часового пояса.

Matt Johnson-Pint 13.07.2014 02:47

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

philfreo 27.03.2017 21:08

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

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

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

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

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

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

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

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

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

  • Некоторые библиотеки, такие как Люксон, используют этот 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 знают только о правиле перехода на летнее время Текущий для своего местного часового пояса. Подробнее об этом здесь.

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

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

Использование географического положения пользователя (т. Е. Его локали) для определения часового пояса также является ошибочным. Пользователи могут захотеть использовать на своем устройстве определенный часовой пояс, который не является местным часовым поясом, даже если он может отображать то же время (или нет). Например. путешественники часто оставляют свои устройства с часовым поясом, установленным на их обычное местоположение, и не ожидают, что даты и время будут использовать другое смещение без уведомления. Я могу говорить здесь из личного опыта… ;-)

RobG 16.08.2019 04:07

Не могу сказать, троллит ли ты меня, Роб. ;) Но ни один из этих подходов не использует их локаль, а скорее настройку на устройстве, так что согласуется с вашей точкой зрения. (Только альтернативный подход, упомянутый в последнем абзаце, будет использовать текущее местоположение.)

Matt Johnson-Pint 16.08.2019 19:07

Подключаемся к терминологическому примечанию: "locale" подчеркнуто нет - географическое положение пользователя. «Локаль» - это группа настроек, таких как язык, числовой формат, календарь и т. д. Например, локаль de_DE определяет немецкий как язык по умолчанию, евро как валюту по умолчанию, запятые как десятичный разделитель, точки как разделитель тысяч и григорианский как календарь. См. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

azernik 25.02.2020 07:01

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

К сожалению, этот заголовок, по-видимому, в основном предназначен для ответов, а не для запросов: «Пользовательский агент МОЖЕТ отправить поле заголовка Date в запросе, хотя обычно не будет этого делать, если не предполагается, что он передает полезную информацию серверу». Я только что проверил, а Firefox не отправляет.

IMSoP 02.02.2015 20:43

С JavaScript и PHP это просто:

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

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

Предполагая, что клиент creates a new account, данные получает post, и мне нужно, чтобы insert/updatedate_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.

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

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

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

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

В настоящее время я больше не рекомендую moment.js. В настоящее время существуют гораздо меньшие альтернативы (dayjs, дата-фнс). Момент огромный.

Dan Dascalescu 17.03.2019 08:45

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

Я думаю, что более простой процесс - вызвать Intl.DateTimeFormat().resolvedOptions().timeZone и отправить его на веб-сервер. Ссылка: stackoverflow.com/questions/9772955/…

Michael Tsang 20.02.2019 07:56

Нет такого способа определить часовой пояс в реальном HTML-коде или любой строке user-agent, но вы можете сделать базовую функцию, получая ее с помощью JavaScript.

Я пока не знаю, как писать код на JavaScript, поэтому выполнение моей функции может занять время.

Однако вы можете попытаться получить фактический часовой пояс также с помощью JavaScript с функцией getTzimezoneOffset() в разделе Date или просто new Date().getTimezoneOffset();.

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