在应用程序中管理时区和位置感知时间?

时间:2011-11-21 20:46:39

标签: c# .net sql-server silverlight

在我的应用程序(Silverlight客户端 - 服务器 - SQL Server数据库)中,SQL Server作为后端,我需要在不同的时区进行各种计算和显示时间。我需要在客户端,服务器端和数据库端进行计算。

这是我需要同时使用各个时区的应用程序,它不是典型的“Local vs UTC” 所有数据都将以UTC格式存储,但我需要转换为: 1.地点时间 2.用户的时间

所以,让我们说如果我们谈论航空旅行 - 我将以UTC时间存储,但用户将在出发/到达时区看到它们。

我正在寻找最佳实践,如果我对如何接近它有错误,可能会纠正我:

  1. 数据库将包含“TimeZones”表,其中包含时区名称,ID,时间偏移等信息,此区域是否为DST
  2. 数据库中的用户和位置将链接到TimeZone
  3. 在客户端和服务器(.NET)上,我将加载TimeZones表并将其缓存在我的共享DateTimeService中。通过这种方式,我可以在需要时绑定UI,并在一个中心位置完成所需的所有转换
  4. UI /服务器上的计算将使用.NET的内置DateTime& TimeZoneInfo功能
  5. 困扰我的是,我将不得不在SQL Server和.NET上执行两组不同的功能来进行转换。我不想要SQL Server中的CLR代码。我很可能会在T-SQL中手动编写时间转换函数,我将让TimeZoneInfo在.NET端为我工作。

    另外,我将不得不在DB中随处可见FK,我参考TImeZOne表。这将导致其他问题,如不断加入等。

    您如何在数据库和应用程序中管理此类信息?

1 个答案:

答案 0 :(得分:1)

正如djacobson所提到的,最好的办法是将转换从数据库中推出。将时间存储为数据库中的UTC。要求客户端进行时区转换,并且仅在UTC时间与服务器通信,以简化服务器的任务。如果服务器由于某种原因确实需要对时区进行日期识别,请让客户端或服务传递偏移参数以及DT参数,这样服务器就可以将其用作修饰符并仍然可以使用UTC时间。我想传递调整DT参数以使其达到UTC所需的分钟数,但只要您确保一致地处理请求,还有其他同样有效的方法。

这是我最近工作的项目的简化示例,该项目是针对移动设备的会议安排应用程序。 UTC -6中的客户请求从2011年11月20日开始的所有会议将通过MinutesToAdjustBy = 360StartDate = {11/16/2011}。带宽要求规定服务器执行过滤。服务器应用程序将从此客户端的DB获取所有记录,然后通过选中record.MeetingDate.AddMinutes(MinutesToAdjustBy).Date == StartDate.Date来过滤掉未命中。将所有通过此检查的记录返回给客户端,而不更改返回数据;即,MeetingDate仍然是UTC。这避免了在转换为UTC或从UTC转换日历日期时的问题,并允许您的后端不知道实际时区。

顺便说一句,我的示例中的性能可以通过在所请求日期的任何一个方向上在1个日历日内查询所有StartDate客户端记录的数据库来改进,以便显着减少记录数量取出。

编辑:我在最初的回答中误解了这个问题,并且对转换发生的位置问题感到困惑。我将离开上述内容,因为它与如何处理转换的问题相关,但它没有正确回答这个问题。

如果您愿意相信您的客户的系统将具有正确的(更重要的是,所有具有相同的)时区的注册表项并且将支持此方法,您可以存储并传递TimeZoneInfo.Id对于出发和到达时区,并在客户端转换期间使用TimeZoneInfo.FindSystemTimeZoneById()。它给客户带来了很多信任,但影响很小。

如果您愿意信任外部服务,您可以像上面那样对目的地和到达TZ ID进行类似的存储,然后调用服务客户端(或服务器端,如果绝对必要)来获取所需的服务信息。请参阅this question

如果这些都不合适,那么您可能会陷入制作自己的时区表并将其缓存在您的服务中,正如您在问题中提到的那样。同样,在这里您可以遵循相同的基本设计:存储两个TZ ID,并让客户端从服务中获取所需的信息以便完成工作。