是否有一种标准的方法可以让服务器在网页中确定用户的时区?

可能来自HTTP报头或用户代理字符串的一部分?


当前回答

JavaScript是获取客户端本地时间的最简单方法。我建议使用XMLHttpRequest发送回本地时间,如果失败,则退回到基于IP地址检测到的时区。

至于地理定位,我已经在几个项目中使用了MaxMind GeoIP,它工作得很好,尽管我不确定他们是否提供时区数据。这是一项你付费的服务,他们每月更新你的数据库。他们提供多种网络语言的包装器。

其他回答

我所见过的最流行的(==标准?)确定时区的方法是简单地询问用户自己。如果你的网站需要订阅,这可以保存在用户的个人资料数据。对于anon用户,日期可以显示为UTC或GMT或类似的格式。

我可不想自作聪明。只是有时候有些问题在任何编程环境之外都有更好的解决方案。

不要使用IP地址来明确地确定位置(以及时区)——这是因为使用NAT、代理(越来越流行)和vpn, IP地址不一定真实地反映用户的实际位置,而是反映实现这些协议的服务器所在的位置。

类似于美国的区号对于定位电话用户不再有用,因为号码可携性很流行。

IP地址和上面显示的其他技术对于建议用户可以调整/纠正的默认值很有用。

有几种方法可以在浏览器中确定时区。如果您的浏览器提供并支持一个标准函数,那么您就应该使用它。下面是用不同格式获取相同信息的三种方法。避免使用基于特定假设或硬编码区域列表进行猜测的非标准解决方案,尽管如果没有其他办法,它们可能会有所帮助。

一旦你有了这个信息,你可以把它作为一个非标准的请求头传递给服务器,并在那里使用它。如果你还需要时区偏移量,你也可以在头文件中或请求有效载荷中传递给服务器,可以使用dateObj.getTimezoneOffset()来检索。

使用Intl API获取Olson格式(标准和推荐的方式):注意,这不是所有浏览器都支持。有关浏览器对此的支持的详细信息,请参阅此链接。 这个API可以让你获得Olson格式的时区,例如亚洲/加尔各答,美国/纽约等。

Intl . DateTimeFormat () timeZone resolvedOptions()。

使用Date对象获得较长的格式,如印度标准时间,东部标准时间等:这是所有浏览器支持的。

let dateObj =新的日期(2021,11,25,09,30,00); / /然后 dateObj.toString () / /收益率 2021年12月25日星期六09:30:00 GMT+0530(印度标准时间)//我位于印度(IST)

注意,字符串包含长格式和短格式的时区信息。你现在可以使用regex来获取这些信息:

let longZoneRegex = /\((.+)\)/; dateObj.toString () .match (longZoneRegex); / /收益率 ['(印度标准时间)','印度标准时间',索引:34,输入:' 2021年12月25日星期六09:30:00 GMT+0530(印度标准时间)',组:未定义] //注意output是一个数组,所以使用output[1]来获取时区名称。

使用Date对象获取短格式,如GMT+0530, GMT-0500等:所有浏览器都支持。

类似地,你也可以得到短格式:

let shortZoneRegex = /GMT[+-]\d{1,4}; dateObj.toString () .match (shortZoneRegex); / /收益率 ['GMT+0530',索引:25,输入:' 2021年12月25日星期六09:30:00 GMT+0530(印度标准时间)',分组:未定义] //注意output是一个数组,所以使用output[0]来获取时区名称。

在PHP中获取有效的TZ数据库时区名称是一个两步过程:

With JavaScript, get timezone offset in minutes through getTimezoneOffset. This offset will be positive if the local timezone is behind UTC and negative if it is ahead. So you must add an opposite sign to the offset. var timezone_offset_minutes = new Date().getTimezoneOffset(); timezone_offset_minutes = timezone_offset_minutes == 0 ? 0 : -timezone_offset_minutes; Pass this offset to PHP. In PHP convert this offset into a valid timezone name with timezone_name_from_abbr function. // 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中检测用户时区。它还包含一个演示。

到目前为止,还没有报告客户端时区的HTTP标头,尽管有人建议将其包含在HTTP规范中。

如果是我,我可能会尝试使用客户端JavaScript获取时区,然后使用Ajax或其他工具将其提交给服务器。