以UTC格式存储的SQL DateTime基于偏移量获得一天的开始

时间:2017-09-30 21:27:40

标签: sql sql-server datetime utc localtime

这可能是有史以来对SQL和日期/时间值有关的最可悲的问题,但我可以使用一些帮助......

尝试设置将在东部,山区,中部和太平洋时区的指定时间运行的功能/作业(理论上其他区域也可以)。系统将识别哪些用户属于每个时区,然后从系统输出数据,突出显示他们当天所完成的工作。

这是我的挑战,我知道所有日期/时间值都以UTC格式存储在SQL DB中。我可以应用偏移量并将这些时间转换为本地时区。不是将成千上万的日期/时间值转换为当地时间并在那里进行比较,而是简单地调整存储过程中UTC的开始和结束日期/时间值。(/ p>)

在西海岸,它现在只有2017-09-30 14:30:00,而UTC是2017-09-30 21:30:00,这清楚地表明了现在7小时的时区差异,这意味着“今天”从用户的角度来看从技术上开始2017-09-30 07:00:00并以UTC中的2017-10-01 06:59:999结束。

为用户开始的日期和日期值结束建立这些日期/时间值的最佳方法是什么?

更新

我目前有这段代码......

DECLARE @InputDate as DateTime
DECLARE @InputEndDate as DateTime
DECLARE @InputDateWithOffset as DateTimeOffSet
DECLARE @InputEndDateWithOffset as DateTimeOffSet

SET @InputDate = '2017-09-28'
SET @InputDateWithOffset = @InputDate AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time'

SET @InputEndDate = DATEADD(day, 1, DATEADD(ms, -3, @InputDate))
SET @InputEndDateWithOffset = @InputEndDate AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time'

SELECT 
    @InputDate AS InputDate, @InputEndDate AS InputEndDate, 
    @InputDateWithOffset AS InputDateWithOffset, 
    @InputEndDateWithOffset AS InputEndDateWithOffset

其中输出以下内容: enter image description here

最后两列似乎是正确的,因为它表示输入日期的开始和输入日期的结束,因为输入日期将是执行的本地日期......

当我使用UTC中的日期时间对我的表值采用@InputDateWithOffset@InputEndDateWithOffset时,看来返回的唯一日期是那些落在2017-09-28上并且似乎忽略了比较的日期抵消日期/时间。

1 个答案:

答案 0 :(得分:1)

您的更新大多正确无误。但是,您错过了“一天开始”操作,需要在当地时间完成。

考虑:

DECLARE @InputStartUTC as DATETIME, @InputEndUTC as DATETIME
DECLARE @InputStartDTO as DATETIMEOFFSET, @InputEndDTO as DATETIMEOFFSET
DECLARE @InputStartDTOatStartOfDay as DATETIMEOFFSET, 
        @InputEndDTOatStartOfDay as DATETIMEOFFSET

DECLARE @tz as VARCHAR(50) = 'Pacific Standard Time'

SET @InputStartUTC = '2017-09-28 00:00:00'
SET @InputStartDTO = @InputStartUTC AT TIME ZONE 'UTC' AT TIME ZONE @tz
SET @InputStartDTOatStartOfDay = CAST(CAST(@InputStartDTO as DATE) as DATETIME)
                                 AT TIME ZONE @tz

SET @InputEndUTC = DATEADD(day, 1, @InputStartUTC)
SET @InputEndDTO = @InputEndUTC AT TIME ZONE 'UTC' AT TIME ZONE @tz
SET @InputEndDTOatStartOfDay = CAST(CAST(@InputEndDTO as DATE) as DATETIME)
                               AT TIME ZONE @tz

SELECT 
    @InputStartUTC as InputStartUTC, @InputEndUTC as InputEndUTC, 
    @InputStartDTO as InputStartDTO, @InputEndDTO as InputEndDTO,
    @InputStartDTOatStartOfDay as InputStartDTOatStartOfDay,
    @InputEndDTOatStartOfDay as InputEndDTOatStartOfDay

另外,请注意我没有从结束日期减去3毫秒。而不是试图找出.997或.999或其他什么,更好的方法是使用半开区间查询。换句话说,start <= value AND end > value