管理SQL Server中的时区和夏令时

时间:2015-02-21 17:00:11

标签: c# sql sql-server sql-server-2012 dst

我们目前正在尝试在我们的应用程序中实现时区管理。我们的服务器在印度。我们将在服务器时间内保存所有条目。但是当来到客户端时,我们需要在客户端时间显示数据。所以我得出这样的结论:从前端获取客户端时区并使用数据库中的以下代码将服务器时间转换为客户端时间将解决问题。

DECLARE @ServerTime DATETIMEOFFSET(7) = '2015-02-21 22:06:08.6862774 +05:30'   -- My server time
DECLARE @ClientTime DATETIMEOFFSET(7) = '2015-02-21 12:38:09.5421899 -04:00' -- My Client Time

SELECT SWITCHOFFSET(@ServerTime, DATEPART(TZ, @ClientTime))

我的问题是

  • 还有更好的选择吗?
  • 可以从前端(C#)完成吗?

最后也是最重要的问题是:

  • 如果客户端计算机处于夏令时,我该如何管理?

任何支持将不胜感激。

3 个答案:

答案 0 :(得分:1)

您可以在.NET中以更简单的方式执行此操作,因为.NET具有一些“自动”机制来处理此问题。

例如:如果您的客户端应用程序调用Web服务并以本地时间(date.Kind == DateTimeKind.Local)作为参数发送DateTime,则日期将使用偏移量序列化(“2015-08-19T14:21+ 01:00“)在服务器端,日期将被反序列化并转换为服务器的本地时间。例如,使用上面的日期,如果服务器是UTC,则DateTime对象的值为“2015-08-19 13:21:00”(但是您将无法获得有关客户端所在时区的信息以及日期已创建)。如果再次向客户发送日期,则进行逆转换,并且日期将在客户端上具有原始值。 这样服务器将始终使用本地时间处理日期,客户端将始终以当地时间处理日期,尽管他们不知道彼此的时区。

我认为这种机制不能很好地处理过去的古代日期,因为夏令时,这可能受到信息窗口关于夏令时的限制(作为时区的示例“E.南美标准时间” Windows 8仅具有2006年至2040年的DST信息,这意味着2006年之前的日期可能会被误解。)

话虽如此,我认为处理不同时区的最佳解决方案是使用UTC并在向用户显示日期时转换为本地时间,或者始终使用DateTimeOffset而不是DateTime(DateTimeOffset也有关于日期时区的信息)。

答案 1 :(得分:0)

虽然最好在客户端代码中执行此操作,但如果您决定需要在SQL Server中直接使用时区,则可以使用我的SQL Server Time Zone Support项目。

示例:

SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')

答案 2 :(得分:0)

您可以使用:

SELECT CONVERT(datetime,'2019-03-11 11:59:59') 
AT TIME ZONE 'UTC' 
AT TIME ZONE 'US Eastern Standard Time';

它还可以处理夏时制。