在 SQL 服务器中管理时区和夏令时

Managing Time zone and Daylight Saving in SQL Server

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

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))

我的问题是

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

如有任何支持,我们将不胜感激。

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

示例:

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

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

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

由于夏令时的原因,我认为这种机制不能很好地处理过去的古代日期,这可能受到 windows 关于夏令时的信息的限制(例如时区 "E. South America Standard Time" windows 8 只有 2006 年到 2040 年的 DST 信息,这意味着 2006 年之前的日期可能会被误解。

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

您可以使用:

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

它也处理夏令时。