仅当datetime可用时,正确处理SQL Server中的日期的方法

问题描述 投票:0回答:1

我们使用名为“Aras Innovator”的PLM软件,需要将日期存储为自定义项目属性。该软件使用Microsoft SQL Server存储其数据,并且正式支持在数据库级别访问属性。

但是,我们的问题是该软件仅支持日期时间,而不是日期。并且日期以UTC格式存储 - 因此当我们从中欧的客户端存储“2020-01-01”时,它在数据库中变为“2019-12-31 23:00”左右(当天午夜前1小时)之前)。然后检查“> = 2020-01-01”的查询无法找到这些行。

软件制造商说:

没有标准功能只能存储月和日;快速选项可以是将其存储为字符串,并在需要时对输入的字符串进行编程验证。

关于直接SQL查询,所有日期都以UTC格式存储,以便与多个时区兼容。当通过标准API访问时,它们会自动转换。使用SQL直接访问时,可以使用CD映像的Aras Innovator 11.0 - 配置国际化指南中描述的函数ConvertToLocal,第5.3节:

SELECT item_number,innovator.ConvertToLocal(created_on,'Eastern Standard Time')AS CreatedOn FROM innovator.Document

ConvertFromLocal可用于指定您要查询的日期,而不是要求以UTC格式发送这些日期。

我不相信使用字符串会是一个很好的解决方案。但不相信他们的“ConvertTo / FromLocal”功能也是一个很好的解决方案。当然必须有一些其他方法直接在SQL Server中处理它?

sql-server date datetime timezone
1个回答
0
投票

SQL Server 2016引入了AT TIME ZONE statement

考虑:

SELECT CONVERT(date, TheDateTime AT TIME ZONE 'UTC'
                                 AT TIME ZONE 'Central Europe Standard Time')

以上将首先将TheDateTime字段从datetime或(datetime2)转换为具有零偏移(UTC)的datetimeoffset类型。然后它会将它转换为Central Europe Standard Time区域,最后将其转换为date类型,删除任何时间信息。

至于你的陈述:

...> = 2020-01-01“然后因此无法找到这些行。

您应该考虑转换相反的方向,以便您查询UTC时间 - 这将是sargable。例如:

SELECT ...
WHERE TheDateTime >= CONVERT(datetime,
                     '2020-01-01' AT TIME ZONE 'Central Europe Standard Time'
                     AT TIME ZONE 'UTC')

当然,您可以提前完成表达式的整个右侧并使用局部变量。同样,如果从应用程序调用此查询,则可以在应用程序代码中转换为UTC,而不必在SQL Server中执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.