在ExpressJS中获取客户端的时区偏移量

时间:2015-07-23 18:44:09

标签: javascript node.js express timezone

我正在寻找一种在ExpressJS中获取客户端时区偏移的方法(例如,使用req对象,会非常棒)。

4 个答案:

答案 0 :(得分:8)

如果您控制客户端,则可以do this with client-side JavaScript

如果您没有(例如,您正在构建像API这样的服务器端组件),那么您就无法将其从HTTP请求中删除(除非您正在使用会议,但即使这不一定可靠)。

从好的方面来说,如果它只是服务器端,你也不应该担心:将所有日期对象设置为UTC或Unix时间戳,并将其留给客户端开发人员来处理时区

答案 1 :(得分:1)

即使您有时区偏移量,但这并不意味着您在客户端拥有正确的时间,因为某些区域有夏令时"

但是,你可以猜测"考虑以下数据,用户所在的时区:

  1. req.get(' Accept-Language'),用户可能居住的国家/地区;
  2. req.ip,搜索数据库并找出大致位置;
  3. 客户端(新日期).getTimezoneOffset(),用于时区偏移;
  4. 最后,通过计算上述结果,你的猜测几乎应该存在。时区应存储在类似于' America / New_York'的字符串中。但不是时区偏移数。

    http://momentjs.com/timezone/应该是处理时区的好工具。

    保存"几乎正确"时区,不要忘记离开用户可以更改的地方。

答案 2 :(得分:0)

正如其他人提到的那样,无法通过HTTP获取客户端浏览器/操作系统时区偏移,因此您需要从客户端发送此数据。

对于我来说,我有一个需要登录的应用程序...因此我可以存储用户的首选项。默认设置为使用浏览器时区,但用户也可以配置特定时区以使用所有时间,而不是使用存储在其用户个人资料中的所有时间(例如America/DallasEurope/Amsterdam)。

我不相信浏览器的时间正确无误。用户可能还搞砸了他们的操作系统时区设置...因此时区偏移量也可能不正确。但是,大多数现代OS会根据Geo-IP隐含的位置自动设置时区...因此,对于许多用户而言,能够在世界各地旅行并登录到应用程序并查看他们所处的本地时区中的日期/时间的便利性值得为用户体验付出努力。一直希望查看特定时区的用户可以对其进行配置,而我们将使用该首选项。

我的操作方式如下...在登录表单上添加一个隐藏字段并使用javascript设置值。用户登录时,将此时区偏移量存储在会话中。如果用户尚未设置首选时区,则在渲染日期/时间时将使用此偏移量。这意味着,如果您的会话时间很长,并且用户可以在各个国家/地区之间来回走动...他们仍然会显示旧的时区偏移,直到下一次注销/登录为止。您当然可以更频繁地获取此数据,或者甚至可以根据每个请求获取此数据...但是出于我的目的,登录时获取此数据就足够了。我的会话无论如何都因IP地址更改而过期...是的。当然,如果他们的会话经过了夏令时切换,则偏移量直到下一次登录时才是准确的(假设他们的OS /浏览器TZ首先是正确的)。

客户端

<input type="hidden" name="tzOffset" id="tzOffset">
<!-- ... -->
<script>
var tzOffset = new Date().getTimezoneOffset(),
    tzInput = document.getElementById('tzOffset');
tzInput.value = tzOffset*(-1);
</script>

请注意,我将其乘以-1,因为我将使用moment.js在快速端进行格式化,并且偏移量是向后的(本地的utc偏移量与utc的本地偏移量)。您也可以在服务器端执行此操作。在使用它之前,您可能还应该验证此数字……这里只是最少的示例代码。

服务器端

然后,如果成功登录,则在服务器端(快速),我将tzOffset值保留在会话中。

然后在用moment-timezone格式化日期时,我可以执行以下操作:

function (date) {
    var userTZ,     // user specified TZ like Europe/Berlin
        userTZoffset, // tzOffset we got from login form
        userDateFormat,  // user specified date format (or default)
        userTimeFormat; // user specified time format (or default)

    if (userTZ)
        return moment(date).tz(userTZ).format(userDateFormat+' '+userTimeFormat+' zz');
    else
        return moment(d).utcOffset(userTZoffset).format(userDateFormat+' '+userTimeFormat+' ZZ');
}

ZZ格式用于以数字偏移量格式显示时区(与我们使用来自客户端的固定数字偏移量有关。

zz格式用于以字符格式(例如PDT,PST,EST等)显示时区,这在我们具有像欧洲/柏林这样的时区而不是固定的数字偏移量时才有意义。

另一种方法

将原始日期推送到客户端并进行客户端格式化。缺点是缺乏控制和一致性,而有更多的js推送到浏览器。如果愿意的话,此刻还可以在客户端运行。

我只是根据用户区域设置和用户偏好在服务器端配置格式化程序,然后将这些格式化程序公开显示在我的哈巴狗模板中。到目前为止,它对我来说效果很好。

有趣的故事

我有一个同事在他们的计算机上手动设置了错误的时区,所以时间是错误的。他们没有固定时区,而是禁用了网络时间,并手动将时间设置为“正确”时间。

然后,当每个人都出现在他们计划迟到一个小时的会议上时,他们变得脾气暴躁。

所以是的...不能保证客户端时间或时区偏移量是正确的。

答案 3 :(得分:-2)

有些人喜欢使用库momentJS来处理任何与时间有关的事情,但我相信Javascript中的Date对象足以满足您的要求并且不需要库。 getTimezoneOffset是您需要的。我希望这有帮助!如果您有其他问题,请告诉我们!

相关问题