SQL查询从GMT更新DB中的现有DateTime字段和值到PST

时间:2015-03-25 21:57:01

标签: sql sql-server database datetime

我正在寻找一种最好的方法来编写一个查询,该查询获取数据库中的现有DateTime字段/值(超过50K行)并将DateTime值更新为不同的时区。我想要做的是将现有的日期/时间值从GMT时间(当前服务器时间)更改为PST(我认为将减去7小时)。我想更改数据库中的值然后我将服务器上的服务器时间更改为PST以反映时区,以便所有新记录显示PST时区。

对此有任何帮助,我们将不胜感激,感谢您的时间。

3 个答案:

答案 0 :(得分:1)

你可能根本不应该这样做。将数据保存在数据库中的GMT(实际上是UTC)中,并根据需要将其转换为应用程序逻辑中的太平洋时间。例如,如果从.NET应用程序连接到SQL Server,请从数据库中查询UTC时间并使用TimeZoneInfo.ConvertTimeFromUtc

进行转换。

最大的原因是太平洋时间使用daylight saving time。因此,虽然部分时间它遵循PST(UTC-8),但在夏季它遵循PDT(UTC-7)。这意味着需要调整的时间是变量,并且取决于日期本身。

不仅如此,在回退过渡期间发生的值在当地时间不明确。例如,2015-11-01凌晨1:30在太平洋时间发生两次。如果您将所有数据转换为太平洋时间,则可能会丢失一些信息。

如果确实需要在SQL Server中直接在时区之间进行转换,请考虑使用我的SQL Server Time Zone Support项目。例如:

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

答案 1 :(得分:0)

不幸的是,SQL Server没有任何内置的时区转换功能。但是,这可以通过SQLCLR完成。您可以使用DateTime.ToLocalTime()方法创建标量用户定义函数。

是的,从技术上讲,您可以使用TimeZoneInfo类,其中包含ConvertTime(DateTime, TimeZoneInfo, TimeZoneInfo)ConvertTimeFromUtc(DateTime, TimeZoneInfo)等方法,但TimeZoneInfo类要求程序集具有{{1} } PERMISSION_SETUNSAFE可以DateTime运行。坚持SAFE方法的唯一缺点是它们只能在UTC和服务器的本地时间之间进行转换,而DateTime可以在任何两个给定时区之间进行转换。 / p>

由于您的数据已经是GMT / UTC,只有在您更改服务器的时间后,使用TimeZoneInfo转换为Pacific *时间相当容易在更新数据之前的区域,而不是之后(如问题中所述)。此时您可以执行以下操作:

DateTime.ToLocalTime

* 请注意我使用过" Pacific"时间而不是PST,因为太平洋时间可以是PST或PDT,具体取决于夏令时。因此,尝试通过简单地执行ALTER TABLE [SchemaName].[TableName] ADD [IsConverted] BIT NULL; -- make sure we don't convert multiple times WHILE (1 = 1) BEGIN UPDATE TOP (2000) tab SET tab.DateField = dbo.ConvertTimeToLocalTime(tab.DateField), tab.IsConverted = 1 FROM [SchemaName].[TableName] tab WHERE tab.IsConverted IS NULL; IF (@@ROWCOUNT = 0) BEGIN BREAK; END; END; -- Remove the temporary tracking field, but not until all rows are converted IF (NOT EXISTS( SELECT * FROM [SchemaName].[TableName] tab WHERE tab.IsConverted IS NULL ) ) BEGIN ALTER TABLE [SchemaName].[TableName] DROP COLUMN [IsConverted]; END; 转换对于某些行是正确的,但不是所有行。

此外,对于那些对此特定转换函数感兴趣的人,它在SQL#库的完整版本(我是其作者)中可用(尽管不是免费的)。有一些博客文章展示了如何做到这一点,虽然我没有看到一个遵循最佳实践,以便它将表现最佳。当然,如果这是一次性转换,那么价格的最佳表现肯定不如效率低但免费的重要: - )。

答案 2 :(得分:-1)

您可以使用ALTER DATABASE语句的SET TIME_ZONE子句更改数据库时区。例如:

ALTER DATABASE SET TIME_ZONE='Europe/London';ALTER DATABASE SET TIME_ZONE='-05:00';

您可以参考以下链接了解更多详情。 http://docs.oracle.com/cd/E11882_01/server.112/e10729/ch4datetime.htm#NLSPG263