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

Мне нужно знать, в какой часовом поясе находятся мои пользователи, на основе их IP или HTTP-заголовка.

Я получил много ответов на этот вопрос, но я не мог понять ответ. Некоторые говорят, что использование -new Date().getTimezoneOffset()/60 ( отсюда ). Но что это значит?

У меня есть date_default_timezone_set("Asia/Calcutta"); в корне моей страницы (index.php). Поэтому для этого я должен динамически установить часовой пояс и установить его вместо Asia/Calcutta .

Подводя итог ответу Мэтта Джонсона с точки зрения кода:

 <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"> </script> <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.4/jstz.min.js"> </script> <script type="text/javascript"> $(document).ready(function(){ var tz = jstz.determine(); // Determines the time zone of the browser client var timezone = tz.name(); //'Asia/Kolhata' for Indian Time. $.post("url-to-function-that-handles-time-zone", {tz: timezone}, function(data) { //Preocess the timezone in the controller function and get //the confirmation value here. On success, refresh the page. }); }); </script> 

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

Если у вас есть координаты местоположения (например, с мобильного устройства GPS), вы можете найти часовой пояс, используя один из этих методов . Однако геолокация по IP-адресу не является отличным решением, поскольку часто IP-адрес провайдера или прокси-сервера, который может находиться в другом часовом поясе.

Существуют некоторые стратегии, которые вы можете использовать, чтобы попытаться определить часовой пояс, например, используя библиотеку jsTimeZoneDetect , которая является отличной отправной точкой, но недостаточно несовершенна, что вы не можете просто полагаться только на нее. Если вы используете moment.js, в момент-времени есть встроенная функция, называемая moment.tz.guess() которая делает то же самое.

Идея использования функции getTimezoneOffset() JavaScript ошибочна в том, что вы не получаете часовой пояс – только одно смещение для определенной даты. См. Раздел wiki темы тегов TimeZone под названием «TimeZone! = Offset».

Однако вы смотрите на это, в конечном счете, вам нужно решить один из двух подходов:

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

ИЛИ

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

Я обсуждаю это более подробно (с точки зрения AC #) в этом ответе .

зависимости:

  1. http://www.maxmind.com/download/geoip/api/php/php-latest.tar.gz
  2. http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

     //Get remote IP $ip = $_SERVER['REMOTE_ADDR']; //Open GeoIP database and query our IP $gi = geoip_open("GeoLiteCity.dat", GEOIP_STANDARD); $record = geoip_record_by_addr($gi, $ip); //If we for some reason didnt find data about the IP, default to a preset location. if(!isset($record)) { $record = new geoiprecord(); $record->latitude = 59.2; $record->longitude = 17.8167; $record->country_code = 'SE'; $record->region = 26; } //Calculate the timezone and local time try { //Create timezone $user_timezone = new DateTimeZone(get_time_zone($record->country_code, ($record->region!='') ? $record->region : 0)); //Create local time $user_localtime = new DateTime("now", $user_timezone); $user_timezone_offset = $user_localtime->getOffset(); } //Timezone and/or local time detection failed catch(Exception $e) { $user_timezone_offset = 7200; $user_localtime = new DateTime("now"); } echo 'User local time: ' . $user_localtime->format('H:i:s') . '<br/>'; echo 'Timezone GMT offset: ' . $user_timezone_offset . '<br/>'; 

Ссылка: Местное время посетителя SGet, время восхода и захода солнца по IP с MaxMind GeoIP и PHP by Stanislav Khromov

Одно из них – спросить их! Особенно в тех системах членов, где вы можете захватить / зарегистрировать пользователя – дать им выбор в этот момент. Простой, но точный.

Это прекрасно работает …

  echo <<<EOE <script type="text/javascript"> if (navigator.cookieEnabled) document.cookie = "tzo="+ (- new Date().getTimezoneOffset()); </script> EOE; if (!isset($_COOKIE['tzo'])) { echo <<<EOE <script type="text/javascript"> if (navigator.cookieEnabled) document.reload(); else alert("Cookies must be enabled!"); </script> EOE; die(); } $ts = new DateTime('now', new DateTimeZone('GMT')); $ts->add(DateInterval::createFromDateString($_COOKIE['tzo'].' minutes')); 

Часовой пояс недоступен в заголовке HTTP, но страна (аббревиатура) находится в заголовке ACCEPT_LANGUAGE. Это будет нечто вроде «en-US» (США – код страны). Это можно комбинировать с информацией JavaScript, чтобы получить представление о часовом поясе пользователя.

Это то, что я использую в JS:

 function timezone() { var now = new Date(); var jano = new Date(now.getFullYear(), 0, 1).getTimezoneOffset()/-60; var julo = new Date(now.getFullYear(), 6, 1).getTimezoneOffset()/-60; var tz = Math.min(jano, julo); if (jano != julo) tz += ((jano < julo) ? 'S' : 'W') + Math.abs(jano - julo); return tz; } 

Это возвращает строку типа «-6S1» для центральной зоны (стандартное смещение по времени на -6 часов, летнее время действует летом и добавляет 1 час). Я использую cookie, чтобы сделать это доступным для PHP. PHP ищет базу данных TZ для зон, которые соответствуют этому, и страны. Для здесь (US, -6S1) существует 7 соответствующих зон, первая – «Америка / Чикаго».

Кстати, в базе данных есть две зоны, где DST добавляет что-то, кроме 1 часа: лорд-Хоу-Айленд (10.5W0.5) и Тролль-станция, Антарктида (0W2).