如何处理我的Webapp中的时区?


104

我希望更好地了解以下用户故事:

约翰在悉尼工作。早上9:00,他将事件记录在运行在苏黎世服务器上的Web应用程序中。第二天,他前往纽约召开紧急会议,应对该事件进行讨论。在会议期间,他按日期和时间搜索事件。

如我所见,这里至少存在两个问题:

  1. 如何将时间戳保存在数据库中
  2. 如何在用户界面中显示它们

当约翰搜索事件时,他会知道事件发生在9:00,但是他应该在网络浏览器中输入什么?当他仅输入“ 9:00”作为时间戳时,他什么也找不到,因为那可能是苏黎世或纽约时间(由于未找到该事件,因此该应用无法知道它发生在悉尼,所以它无法自动选择正确的时区)。

有什么好方法可以询问用户可能包含时区的时间戳?

第二个问题是如何显示结果。如果来自全球的团队需要讨论事件(并查找相关事件,请考虑一次针对全球多个站点的黑客攻击)。

显示在不同时区创建的时间戳的一个很好的例子是什么?

注意:请专注于需求的可用性。我可以自己找出数据库映射。目前,我不确定工作流程。它应该以非介入/直觉的方式询问/提供必要的信息。如果可以,请提供一个已解决此问题的现有Web应用程序的链接。


5
堆栈溢出通过将所有内容都放入UTC来解决此问题。并不总是很方便,但是它绝对是明确的,并不难实现且有效。
Ry-

2
UTC很诱人,但是OTOH永远不需要在多个时区同步事件。
亚伦·迪古拉

3
如果其中一个涉及的国家/地区制定了在活动预定之后但活动发生之前更改当地时间的法规,该怎么办?系统应如何处理? en.wikipedia.org/wiki/…–
朱利叶斯·穆索

1
数十年来,这种类型的经典时区问题在互联网和印刷品上被打死了,令我惊讶的是,在这个问题上如此生动的输入和丰富之处!
BenSwayne 2012年

2
我想指出一个明显的问题,这又增加了一点复杂性,即大多数西方世界每年都会更改时区两次(“夏令时”),并且发生这种情况的规则全球范围内既不统一,也不一定琐碎,从算法上来讲?
fr13d

Answers:


98

存储时间戳的问题很简单:将它们存储在UTC中。

至于显示它们,将设备的时区设置用作当前时区是很有意义的。就是说,“时间输入”框旁边应该有一个时区下拉列表,默认为设备的当前时区,因此用户可以根据需要进行更改。

您的大多数用户可能不会或几乎不会更改时区。在大多数情况下,您所概述的情况并不常见。通过使用适当的默认值实施下拉菜单,您应该能够使确实走动的人们变得很容易(因为与非旅行者相比,他们通常对时区有更好的了解)。

实际上,更好的方法是保存设备在首次运行时设置的时区,然后查看其是否发生了变化。如果确实发生变化,则用户可能是旅行者,并且可能会从时区下拉列表中受益。否则,仅不显示下拉列表,并将其默认为设备时区(因为用户不需要了解它们)。无论哪种情况,都需要在应用程序中进行设置,以允许用户手动显示/隐藏时区下拉列表。


总结以上内容:

  • 首次运行时,请保存设备设置的时区。
  • 使用该时区作为默认时区。始终假定该时区。
  • 如果设备切换了时区,则添加一个下拉列表以选择事件所在的时区,默认为设备自己的时区。
  • 添加一个选项以手动显示/隐藏此时区下拉菜单。
  • 始终将时间戳记存储在UTC中。

“时区”是什么意思似乎模棱两可。看起来像是参考: en.wikipedia.org/wiki/Tz_database 从我可以看出,“时区”是“区域/位置”,例如“ America / New_York”。那似乎是地理上的,这很棒,因为例如America / Los_Angeles表示PST和PDT取决于地球是否在夏令时运行。如果是这样,问题是我们如何计算区域的UTC偏移的半年变化?另外,由于它们不是地理上正确的“区域”,因此我们称其为什么?
iJames

这是一个很好的答案。关于如何存储时区信息有最佳实践吗?例如-“ PST”或“美国/太平洋”哪个更好?如何轻松地将UTC中的时间戳转换为捕获的用户时区?任何对此的最佳实践将不胜感激。
Patthebug,

27

在我们的应用程序中,通常会在首次注册时存储用户的时区(如在论坛站点上经常看到的那样),并始终以时区显示时间

至于存储日期,UTC是必经之路。转换为UTC并将其粘贴到数据库中。检索时,只需将时间转换为用户设置的时区即可。

我必须解决一个类似的用例,在该用例中,可以将自定义通知(如“新年快乐”)发送给Web应用程序的所有用户。由于用户分布在世界各地,因此我们需要根据时区显示通知。在UTC中存储时间戳可以很好地达到我们的目的,而不会打h。

在您的用例中,如果您不将用户时区存储在某个地方,则除非您开始像gmaps一样使用某种位置检测,否则您将永远无法在不要求用户输入的情况下准确地返回搜索结果。可靠。因此,您每次都需要询问时区,以确保用户知道他在网站中输入的内容。

如果您确实具有时区信息,则应使用时区设置运行整个Web应用程序。因此,当用户确实搜索9:00时,他将使用悉尼时区进行搜索。另一方面,如果他坐在纽约时创建活动,那么他将与悉尼时区一起创建活动。我们通过在显示日期时始终显示时区来解决这种情况。

希望能帮助到你!:)


我认为,在搜索和创建事件时会增加一个时区下拉列表,这是要走的路。(当我需要搜索由同事在纽约创建的活动时,我不想自己做数学)
RasmusWL 2012年

这是一个很好的答案。关于如何存储时区信息有最佳实践吗?例如-“ PST”或“美国/太平洋”哪个更好?如何轻松地将UTC中的时间戳转换为捕获的用户时区?任何对此的最佳实践将不胜感激。
Patthebug,

11
  1. 世界标准时间。把事情简单化。

  2. 使用与用户最相关的时区。

    如果您知道用户将要去该活动或前往悉尼,那么他们在安排前往该活动的交通时将在该时区考虑。他们目前在纽约的事实在很大程度上无关紧要。当然,如果您的应用显示了不同时区的日期,则应始终在日期旁边显示时区,例如EST 09:00

    如果界面不会太杂乱,则可以在事件时区和本地时区中显示日期,例如2012-06-13 09:00 EST(2012-06-12 19:00 EDT)

    我认为搜索是一个类似的问题,但有一个警告:我们可以容忍假阳性(得到我们没有期望的结果),但我们不能忍受假阴性(没有得到我们期望的结果)。

    同样,我将专注于搜索与用户最相关的时区(例如事件时区),并在搜索结果中优先考虑这些结果,但是您也可以返回与用户相关的其他时区中匹配的事件(例如当地时间)。如果这样做,则应在匹配的时区中显示事件日期,尤其是突出显示匹配的文本时。


7

在这里,我给出了最佳可用性的建议,而无需过多考虑实现的可行性。
1.对于第一个将事件存储在db中的问题,每个人都同意将其存储在UTC中

。2.为了提供最佳的用户体验,请保存用户时区的历史记录。如果您可以保存时区更改的时间戳,那就更好了。这将使我们能够自由地进行用户查询,而无需每次都明确指定时区。

因此,使用这些功能,让我们看看如何处理John仅“ 9.00”的搜索查询:
通过上述功能,现在我知道John处于2个时区到日期为止(或获取上述期间的时区列表)。因此,我将从悉尼时区将9.00转换为UTC,并进行查询。还将9.00从NewYork时区转换为UTC,则触发查询。结果,我将向John显示2行,以显示他在悉尼9.00和纽约9.00所做的事情。在这种情况下,纽约行将为空白,但我认为仍应向用户显示,以告知他我们也搜索了该时区。

3.问用户一个可能包含时区的时间戳的好方法是什么?

如果最近更改了他的时区,则每当他登录应用程序时,都应通知您,您的默认时区已更改为本地时区。
创建事件时,可以说用户从下拉菜单中选择时区。通过提供世界上所有时区的选项,不会给用户造成负担。下拉菜单的第一个选项应该是用户设备的当前时区。从他的时区历史中选择了那个时区,然后是UTC,然后是他直到现在从未使用过的剩余时区。

4.如果来自全球的团队需要讨论事件,如何显示结果:

我想将此用例划分为2个或2个以上的团队。
对于仅2个团队,我希望每个团队都在其本地时区和其他团队的时区看到时间戳。(我个人更喜欢在安排会议时在另一端的人所在时区讲话)。对于2个以上的团队,最好考虑更常见的时区,例如UTC。因此,在这种情况下,每个用户都应该在2个时区(UTC时间和默认时区)中看到时间戳。

给出这些建议的目的是,用户不需要在其本地时间进行任何计算,但同​​时,他应该能够在其首选时区与其他用户进行流畅的通信。


2
+1这是一个非常有趣的想法,因为我知道用户在9:00在Sidney中输入了一个事件,因此当同一用户搜索时间(没有明确的时区)时,我应该假定他的意思是“我在哪里那个时候”
Aaron Digulla 2012年

4

好吧,我得到了与众不同的方法:

首先,我事先假设了一些东西。

列出活动的人拥有智能手机(如果是浏览器,则无需做出这些假设)具有以下功能:

  1. 全球定位系统

  2. HTML5功能。

  3. Javascript功能

如何将时间戳保存在数据库中?

解决方案:显然是UTC,我覆盖了以下程序:

步骤1.使用地理位置使用地理位置API的用户

    window.onload = getMyLocation;

    function getMyLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(displayLocation);
        } else {
            alert("Oops, no geolocation support");
        }
    }

    function displayLocation(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        var div = document.getElementById("location");
        div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
    }

步骤2.将(Long,Lat)作为对诸如Yahoo API(使用Flag R将Latitude转换为时区)的TimeZone api中的某些((Lat,Long))的争论,以获取用户的时区。

=> 用户时区是在没有用户输入的情况下确定的(我正在使用它,是因为您不能简单地假设用户知道他所居住的时区,我只在几个月后才知道我的时区:P,太蠢了! )

每个Event表具有TimezoneEvent&也可以具有,CityName 然后创建另一个基于CityNames 进行分类的数据库表。所以这里用户将有两列

|---------------------------------------|
|_____NewYork________|______Sydney______|
|                    |                  |
|Event 1             |  Event 2         |
|____________________|__________________| 

对于UI

=>使用Google Calendar API或某些Calendar API

相关阅读:

  1. 从纬度/经度确定时区,而无需使用Geonames.org等网络服务

  2. 从纬度经度查找时区

我知道它只是说明如何解决此问题。但是,查看使用设备API确定时区时,它对用户的准确性和轻量级

希望能帮助到你!


4
无需地理定位即可轻松找到某人的时区。new Date().getTimezoneOffset()比UTC落后几分钟。
Ry-

@minitech,没错,但是如果该事件在纽约和同一时区的南部发生,该怎么办。我正在使用地理定位,以便您可以在oneshot中精确定位城市(甚至准确)的时区,并以此为基础建立我的数据库表。我想使用设备api最小化用户输入,以提高应用程序的有效性。
uday 2012年

所以?两个地方的时间都一样,所以没有问题。-1
Ry-

@minitech,您可以看到此链接,以了解为什么我建议使用设备api而不是其他方法。webdirections.org/sotmw2011
乌代

2
好的,但是这里的问题不在于获取用户所在的城市。这只是关于获取时区。使用不是在所有浏览器/计算机上都有效的地理位置API,然后重定向到日历API,这是获取一行时区中用户时区的一种不好方法
Ry-

2

对于特定的情况下,我将存储两个本地和UTC时间。UTC在某种程度上很重要,用于将时间同步和转换为当前时区。本地用于搜索和其他信息,例如:

您正在开会:

12:00 Monday (UTC)
9:00 Monday (Sydney, creation local time)
11:00 Monday (Zurich, local time)

或类似的东西。另一种方法是存储创建时区,并在运行时进行转换(如果用户更改会议时间,则特别好)。无论哪种方式,主要原因都是能够恢复原始的创建时间,以便用户可以参考它。


2
  1. 如何将时间戳保存在数据库中

在创建事件时,我将存储UTC时间和本地时区(aka creation time zone)。我将使用存储的内容将UTC时间转换为本地时间(又名creation time),并将其与UTC时间和一起存储creation time zone

注意:我可以从一开始就存储本地时间,但是当用户搜索事件时,希望存在到本地时间的转换。我也希望服务器可以检测到客户端所在的时区。

  1. 如何在用户界面中显示它们

当用户搜索“ 9:00”时,我会搜索UTC OR creation time OR当地时间中包含“ 9:00”的事件。对于结果,我将在其中显示一个结果表creation time(这是为了显示可能在其他时区创建的时间戳,因为我们假设用户正在寻找他在什么时间为任何地点创建事件)。 ,并在下面显示具有相关结果的第二个结果表,可能带有标题“不是您想要的内容?查看相关结果”(其中包括剩余的UTC和本地时间结果)。

总体而言,我将显示UTC时间,本地时间,creation timecreation time zone(即创建该事件的事件的本地时间和时区),按UTC时间排序,因此,如果两个不同,您可以看到哪个事件先发生活动预定在两个不同时区的9:00举行。


1
+1我喜欢在本地时间匹配的所有时区显示所有事件的想法;我对SQL(24x BETWEEN条件)不满意。
亚伦·迪古拉
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.