我们使用称为“ Aras Innovator”的PLM软件,并且需要将日期存储为自定义项目属性。该软件使用Microsoft SQL Server来存储其数据,并且正式支持在数据库级别上的访问属性。
但是,我们的问题是该软件仅支持日期时间,而不支持日期。 日期存储在UTC中-因此,当我们从中欧的一位客户存储“ 2020-01-01”时,该日期在数据库中变为“ 2019-12-31 23:00”左右(当天午夜前1小时)之前)。并且查询“> = 2020-01-01的查询”因此无法找到这些行。
软件制造商说:
没有标准功能只能存储月份和日期;一种 快速的选择可能是将其存储为字符串,然后执行 如果需要,可以对输入的字符串进行编程验证。
关于直接SQL查询,所有日期都存储在UTC中,用于 与多个时区的兼容性。他们是自动的 通过标准API访问时进行了转换。直接访问时 对于SQL,您可以使用 Aras Innovator 11.0-CD上的配置国际化指南 图片,第5.3节:
选择item_number,innovator.ConvertToLocal(created_on,'Eastern 标准时间”),来自创新者的AS CreatedOn.Document
ConvertFromLocal可用于指定您希望查询的日期 而不是要求这些日期以UTC发送。
我不认为使用字符串会是一个好的解决方案。 但不能确信它们的“ ConvertTo / FromLocal”函数也是一个很好的解决方案。 当然,必须有其他方法可以直接在SQL Server中处理此问题?
答案 0 :(得分: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中进行操作。