我希望在一个Rails应用中为时间和考勤系统显示跨越多个时区的数据。一些背景信息:
我们制造电子时间钟。人们将它们放在他们的企业中。员工打卡记录出入工作,并记录其工作时间。
时间钟把某人打卡的时间作为 Unix 时间(例如,我们的 Javascript 时间钟实现会这样获取打卡时间:
当用户登录网站时,around_filter 根据此用户组织的设置为请求设置适当的时区。
(这只是一个简化,实际上还有一个关于用户和他们所在时区之间的连接)
如果我们将每个用户的时区应用于他们打卡的时间,我们会发现他们都处于当地时间早上9点。例如,在UTC时间的2012年09月25日23:00:00.0,在布里斯班(+1000)的时间是2012年09月26日09:00:00.0。Rails的一般做法是使用around_filter为请求设置时区;如果我在这里这样做,每个时间都会相差半个小时,这是不正确的。因此,我正在寻求关于处理来自不同时区的时间的最佳实践建议。
我们制造电子时间钟。人们将它们放在他们的企业中。员工打卡记录出入工作,并记录其工作时间。
时间钟把某人打卡的时间作为 Unix 时间(例如,我们的 Javascript 时间钟实现会这样获取打卡时间:
moment().unix()
)推到我们的 API。然后 API 把它存储在 PostgreSQL 数据库中作为 timestamp without time zone
。当用户登录网站时,around_filter 根据此用户组织的设置为请求设置适当的时区。
问题出现在我们有一个跨越多个时区的组织。例如,一个在每个澳大利亚首都城市都设有办事处的企业将跨越三个时区(夏令时期间更多)。然而,将有一个人在中央办公室需要检查整个组织的数据 - 我们称他们为经理。
假设我们的经理位于悉尼,现在是上午11点。他们管理三个办事处 - 分别位于悉尼、布里斯班(夏令时期间比悉尼晚一个小时)和阿德莱德(夏令时期间比悉尼晚半小时)。员工在当地时间9点打卡。因此,在经理的仪表板上,所有打卡时间都应显示为上午9点。 然而,当前的实现(使用around_filter)将分别显示为上午9点、上午8点和上午8:30,因为它们将使用悉尼的时区进行偏移。
对来自不同城市的员工应用了一层过滤,因此可以告诉系统A来自悉尼,B来自阿德莱德,C来自布里斯班。问题 - 我需要建议 - 是如何最有效地让Rails显示不同时区的偏移。
奖励信用: 除了展示时间,我们还需要读取输入。例如,有人可能早到了5分钟,他们的出勤表需要进行更正。如果当地经理(即布里斯班的某个人)纠正了布里斯班雇员的时间表,那么管理起来应该相对容易——因为我们知道他们在布里斯班,我们可以将请求的时区设置为布里斯班,让ActiveRecord为我们执行偏移量计算。但是,如果总经理(位于悉尼但管理所有时区)想要进行更改,那么我们需要能够根据他们的时区正确转换他们的输入为基于协调世界时(UTC)的时间。关于如何最好地做到这一点的任何建议都将不胜感激。问题的具体例子
在我的数据库中,我的打卡记录表(clok_ins table)看起来像这样:
user_id (integer) | time (timestamp without time zone)
------------------|-----------------------------------
1 | "2012-09-25 22:00:00.0"
2 | "2012-09-25 22:30:00.0"
3 | "2012-09-25 23:00:00.0"
我的用户表看起来像这样:
user_id (integer) | time_zone (varchar)
------------------|-----------------------------------
1 | "Sydney"
2 | "Adelaide"
3 | "Brisbane"
(这只是一个简化,实际上还有一个关于用户和他们所在时区之间的连接)
如果我们将每个用户的时区应用于他们打卡的时间,我们会发现他们都处于当地时间早上9点。例如,在UTC时间的2012年09月25日23:00:00.0,在布里斯班(+1000)的时间是2012年09月26日09:00:00.0。Rails的一般做法是使用around_filter为请求设置时区;如果我在这里这样做,每个时间都会相差半个小时,这是不正确的。因此,我正在寻求关于处理来自不同时区的时间的最佳实践建议。