如何检测用户的时区?
我需要知道当前我的用户在什么时区根据他们的IP或http头。
我在这个问题上得到了很多答案,但我无法理解这些答案。 有人说使用-new Date().getTimezoneOffset()/60
( 从这里 )。 但这是什么意思?
我有一个date_default_timezone_set("Asia/Calcutta");
在我的(index.php)页面的根。 所以为此,我必须dynamic获取时区并将其设置为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),则可以使用这些方法之一find时区。 但是,通过IP地址进行地理定位并不是一个很好的解决scheme,因为IP通常是可能位于另一个时区的ISP或代理服务器。
有一些策略可以用来尝试检测时区,比如使用jsTimeZoneDetect库,这是一个很好的起点,但是不够完善,不能单靠依赖它。 如果您使用的是moment.js,那么moment-time中有一个名为moment.tz.guess()
的内置函数可以做同样的事情。
使用JavaScript的getTimezoneOffset()
函数的想法是有缺陷的,因为你没有得到一个时区 – 只是一个特定date的一个偏移量。 查看TimeZone标签维基的标题为“TimeZone!= Offset”的部分。
然而,你看它,最终你必须决定两种方法之一:
- 要求用户通过某种下拉列表或基于地图的时区select器控件来告诉你他们的时区。
要么
- 仅以UTC发送时间到浏览器,并使用浏览器上的JavaScript转换为用户可能将其计算机设置为的任何本地时区。
我在这个答案中更详细地讨论了这个问题(从ac#的angular度来看)。
依赖关系:
- http://www.maxmind.com/download/geoip/api/php/php-latest.tar.gz
-
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/>';
引用: 通过Stanislav Khromov的MaxMind GeoIP和PHP使用IP访问本地时间,日出和日落时间
一个解决办法就是问问他们! 尤其是在可以捕获/注册用户的成员系统上 – 在这一点上给他们一个select。 简单但准确。
这工作正常…
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”string(标准时间偏移-6小时,夏季时激活DST并增加1小时)。 我使用一个cookie来提供给PHP。 PHP在TZ数据库中search与之匹配的区域和国家。 在这里(美国,-6S1)有7个匹配区域,第一个是“美国/芝加哥”。
顺便说一句,数据库中有2个区域,DST增加了1小时以外的东西:豪勋爵岛(10.5W0.5)和南极洲巨魔站(0W2)。