#sql #sql-server #datetime #timezone #timezone-offset
#sql #sql-сервер #дата-время #Часовой пояс #смещение часового пояса
Вопрос:
У меня есть следующий запрос, который направлен на вычисление пользовательских депозитов с последнего (предыдущего) Суббота с 00:00:00 до конца дня (воскресенье 00:00:00)
Мой столбец даты (плохо называемый ‘datetime’) не содержит никаких сведений о часовом поясе (пример: 2020-09-11 21:52:37.803). Тем не менее, он основан на часовом поясе Латвии / Риги, где расположен мой сервер.
При фильтрации моих строк на основе datetime между 00:00:00 субботы и 00:00:00 воскресенья я не принимаю во внимание тот факт, что мне не нужно фильтровать эту дату по латвийскому времени (время сервера), а по другому времени, которое является «арабским стандартным часовым поясом», в котором находятся мои клиенты.
На сегодняшний день часовой пояс моего столбца даты SQL и арабский часовой пояс равны (UTC 3), но зимой время между зонами будет отличаться.
Как я могу справиться с потенциальной разницей во времени между этими 2 часовыми поясами и быть уверенным, что, несмотря на латвийское время, я всегда фильтрую на основе субботы 00:00:00 и воскресенья 00:00:00 по кувейтскому времени? Должен ли я использовать AT TIME_ZONE
или смещать datetime, чтобы отразить час арабского часового пояса?
SELECT
UserID,
SUM (DEPOSIT) AS deposits
FROM
(
SELECT
UserID,
datetime,
CASE WHEN TranType = 'DEPOSIT' THEN AmountReal ELSE 0 END AS DEPOSIT
FROM
DataFeed
WHERE
datetime >= CAST (
CAST (
IIF (
0 = DATEPART(
dw,
GETDATE()
),
GETDATE(),
DATEADD(
d,
(
(
(
7 0 - DATEPART(
dw,
GETDATE()
)
) % 7
) -7
),
GETDATE()
)
) AS DATE
) AS datetime
) --last saturday at 00:00 0=saturday
AND datetime <= CAST (
CAST (
IIF (
1 = DATEPART(
dw,
GETDATE()
),
GETDATE(),
DATEADD(
d,
(
(
(
7 1 - DATEPART(
dw,
GETDATE()
)
) % 7
) -7
),
GETDATE()
)
) AS DATE
) AS datetime
)
) alltrans
GROUP BY
UserID
Ответ №1:
Я бы посоветовал вам хранить данные в UTC. Таким образом, у вас не будет проблем независимо от часового пояса.
Преобразовать существующие временные метки в UTC. Поскольку вы знаете, что время указано в часовом поясе Латвии, вы можете легко выполнить преобразование и сохранить в UTC. Выполняйте все ваши запросы в будущем, преобразуя время UTC в соответствующий арабский часовой пояс, в котором проживают ваши клиенты. DateTimeOffset
тип данных не учитывает летнее время. Вам необходимо соответствующим образом обработать его в зимнее время, чтобы применить соответствующее смещение при преобразовании даты и времени.
Вы можете использовать TODATETIMEOFFSET для применения преобразования из UTC.
DECLARE @todaysDateTime datetime2;
SET @todaysDateTime = GETUTCDATE()
SELECT TODATETIMEOFFSET (@todaysDateTime, ' 03:00');
Комментарии:
1. Я не могу хранить данные по-другому, поскольку я должен управлять ими как пользователь, доступный только для чтения
2. Si при любом преобразовании времени это должно выполняться на лету
3. @R_life_R,Поскольку данные хранятся в часовом поясе Латвии. Я бы посоветовал вам преобразовать входящие данные в соответствующий часовой пояс, а затем выполнить запросы к данным. Я понимаю, что данные доступны только для чтения. Итак, вы должны обработать это в своем запросе.