【发布时间】:2016-09-18 08:39:57
【问题描述】:
您好,我现在使用时间值来存储时间,这取决于服务器时间,但我的网站将被全世界所有人使用,所以我试图自动检测用户时区。提前致谢
【问题讨论】:
-
浏览器的时区信息不是 http 的一部分,您无法从标头中获取它。我认为你应该使用 jsTimeZoneDetect 库或 php&javascript 等 javascript。
您好,我现在使用时间值来存储时间,这取决于服务器时间,但我的网站将被全世界所有人使用,所以我试图自动检测用户时区。提前致谢
【问题讨论】:
在大多数情况下,您不应该关心或不需要知道用户的时区才能让您的网站正常运行。通常,您将所有内容以 UTC(Unix 时间戳)存储在服务器上,然后将其传输到客户端。然后,使用 javascript,让用户的客户端 UA 在本地处理时区转换。
所以在 PHP 中是这样的。
<?php
$date = new DateTime("2016-09-18 4:45 AM", new DateTimezone("America/New_York"));
$timeStamp = $date->getTimeStamp();
?>
<script>
var timeStamp = <?=json_encode($timeStamp * 1000)?>;
alert(new Date(timeStamp);
</script>
用户根据他们的时区在浏览器中看到格式正确的日期,而服务器不知道或不关心该时区,因为它使用时区不可知的时间戳进行传输。
但是,如果您希望出于传输以外的任何原因可靠地获取用户的时区(即您需要在服务器端应用转换),那么最好只询问用户。所有支持从客户端 UA 收集准确地理位置信息的HTML5 capable browsers now have an Geolocation API(这也适用于移动设备,因为您不能在移动设备中依赖地理位置 IP 信息)。还有一些JavaScript库,如timezone-js,可以根据PHP所依赖的时区数据库准确获取时区。
这样做时要记住的重要一点是,GMT 偏移量不足以知道时区,尤其是在 PHP 中。因为 PHP 依赖于 Olson timezone database identifier,它提供的不仅仅是 GMT 偏移量。例如,在加拿大多伦多和美国纽约,当前的 GMT 偏移量是-0400。但是,在夏令时到来时,两个时区的 GMT 偏移量将是 -0500。
还有更奇怪的城市,例如凤凰城和丹佛,这两个城市位于同一州(亚利桑那州),一个遵守夏令时,另一个不遵守夏令时。因此,根据您所在年份的哪个部分,它们可能会落在相同的 GMT 偏移量中,也可能不会。
$denver = new DateTime("now", new DateTimezone("America/Denver"));
$phoenix = new DateTime("now", new DateTimezone("America/Phoenix"));
var_dump($denver->format('c') , $phoenix->format('c'));
$denver->add(new DateInterval("P4M"));
$phoenix->add(new DateInterval("P4M"));
var_dump($denver->format('c'), $phoenix->format('c'));
上面代码的输出给了我们...
字符串(25)“2016-09-18T03:12:15-06:00” 字符串(25)“2016-09-18T02:12:15-07:00” 字符串(25)“2017-01-18T03:12:15-07:00” 字符串(25)“2017-01-18T02:12:15-07:00”因此,除非您想通过存储 GMT 偏移量并在不同时间错误地应用它而陷入丢失宝贵时区信息的陷阱,否则最好存储 Olson tz 标识符,PHP 可以使用它来准确应用时区转换,而无需有损信息。 timezone-js 库可以帮助您解决这个问题,因为它依赖于来自 tz db 的与 PHP 相同的时区标识符。
【讨论】:
Javascript:
var dateVar = new Date() var offset = d.getTimezoneOffset(); document.cookie = "offset="+offset;PHP:
echo $_COOKIE['offset'];
【讨论】:
你可以用java脚本来做:
用于检测访问者时区的常用 JavaScript 是:
var myDate = new Date();
document.write(myDate.getTimezoneOffset());
基本上需要两件事来确定访问者时区。首先,我们需要确定与格林威治标准时间 (GMT) 的时间偏移量。这可以通过创建两个日期(一个本地日期和一个格林威治标准时间)并比较它们之间的时差来轻松完成:
var rightNow = new Date();
var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);
var temp = jan1.toGMTString();
var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60);
您需要知道的第二件事是该位置是否遵守夏令时 (DST)。由于夏季总是观察 DST,我们可以将 1 月两个日期之间的时间偏移量与 6 月两个日期之间的时间偏移量进行比较。如果偏移量不同,则我们知道该位置遵守 DST。如果偏移量相同,则我们知道该位置不遵守 DST。
var june1 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0);
temp = june1.toGMTString();
var june2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
var daylight_time_offset = (june1 - june2) / (1000 * 60 * 60);
var dst;
if (std_time_offset == daylight_time_offset) {
dst = "0"; // daylight savings time is NOT observed
} else {
dst = "1"; // daylight savings time is observed
}
【讨论】:
您可以使用 IP 地理定位技术从 IP 地址获取访问者的位置,然后获取时区值。虽然 IP 地理定位在位置查询中可能不是 100% 准确,但这应该是您可能获得的最佳非侵入式解决方案。
如果您对此方法感兴趣,可以在http://lite.ip2location.com 下载免费IP 到时区数据库。
【讨论】: