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

本文关键字:位置 感知 时间 时区 应用程序 管理 | 更新日期: 2023-09-27 18:15:16

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

这是一个应用程序,我需要不同的时区在同一时间,它不是典型的"本地与UTC"所有数据将以UTC格式存储,但我需要转换为:1. 地点时间2. 用户的时间

那么,假设我们谈论的是航空旅行-我将以UTC存储时间,但用户将在出发/到达时区看到它们。

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

  1. 数据库将有"TimeZones"表,其中包含时区名称,id,时间偏移量以及该区域是否遵守夏令时
  2. 数据库中的用户和位置将被链接到时区
  3. 在客户端和服务器(. net)上,我将加载TimeZones表并将其缓存在我的共享DateTimeService中。这样我就可以在需要的时候绑定UI,并在一个中心位置完成我需要的所有转换
  4. UI/server上的计算将使用。net内置的DateTime &/ol>

    让我烦恼的是,我将不得不在SQL Server和。net上做两套不同的功能来转换。我不想在SQL Server CLR代码。最有可能的是,我将在T-SQL中手动编码时间转换函数,我将在。net方面让TimeZoneInfo为我工作。

    另外,我将不得不在DB中引用TImeZOne表的任何地方做FK。这将导致其他问题,如不断连接等。

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

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

正如djacobson所提到的,最好的方法是将转换从数据库中推出。在DB中以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转换时更改日历日期的问题,并允许您的后端不知道实际的时区。

作为题外话,在我的例子中,性能可以通过对DB查询在请求日期的1个日历天内StartDate的所有客户端记录来提高,以显着减少获取的记录数量。

编辑:我误解了我最初的答案中的问题,并在转换发生的地方的问题上挂断了电话。我留下上面的内容,因为它与如何处理转换的问题有关,但它并没有正确回答这个问题。

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

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

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