2017-02-10 24 views
2

В нашей системе есть хранимая процедура, которая создает смены для пользователей. Эти сдвиги имеют заданное время начала и окончания и продолжительность. Когда эти сдвиги пересекают границу DST, продолжительность выходит неверно. Возьмите следующий пример:SQL Вычислить продолжительность времени в часах, пересекающих границы DST

declare @start DATETIME = '2017-03-11 22:00:00.000', 
@end DATETIME = '2017-03-12 06:00:00.000' 
select (DATEDIFF(hh, @start, @end)) as 'Elapsed Hours' 

Это возвращает истекшие часы 8 часов. Однако, 3/12 этого года, начинается DST, и часы двигаются на час вперед. Таким образом, фактические истекшие часы за этот период времени - только 7. Я знаю, что в SQL 2016 я могу использовать функцию AT TIME ZONE, чтобы обойти это, но, к сожалению, я должен поддерживать это в SQL 2008 - 2016.

Я нашел другой вопрос, который, кажется, дает мне идею: How to create Daylight Savings time Start and End function in SQL Server Я мог бы использовать эти функции, чтобы получить даты начала и окончания летнего времени, а затем выполнить некоторые вычисления, чтобы увидеть, сдвиг пересекает одну из этих границ, а затем применить соответствующее смещение, но это кажется как уродливый вариант для меня. Прежде всего, не все места наблюдают DST, и не во всех странах используются одни и те же расписания DST ... Поэтому я думаю, что должен быть лучший способ сделать это. Кто-нибудь еще в сообществе столкнулся с этой проблемой и нашел лучший способ справиться с этим?

+1

Гарантировано, что вам никогда не придется определять, что означает 01:30 в первое воскресенье ноября (при условии, что в контексте США)? Когда вы «отступите», у вас будет час повторяющихся периодов, которые вы не можете отсортировать по местному времени. – HABO

+0

Это хороший вопрос. Я не думаю, что нам нужно будет беспокоиться о том, что это за 1:30. Но мне нужно будет изучить это, чтобы увидеть, как приложение ведет себя в течение этого периода времени. – Nathan24

+0

ОК, нет, нам не нужно беспокоиться о том, что это значит. Потому что это вся логика для Shifts/Schedules of work times. Человек, который работает 22:00 - 01:30 в любой день года, всегда будет работать только 3,5 часа даже в день изменения ДСТ, потому что их смена заканчивается до перехода 02:00 на летнее время. Это происходит только тогда, когда кто-то работает через эту границу, поскольку они либо должны работать лишний час, либо работать на один час меньше. – Nathan24

ответ

2

Из-за неопределенности, которую вы определили в расписаниях DST в разных местах, часто рекомендуется выполнять все расчеты дат-времени в формате UTC и отображать их по местному времени для клиентов. Правила DST могут меняться в любое время на основе местных законов, даже из города в город, что UTC, безусловно, лучший способ рассчитать время.

Редактировать для дополнительной ясности: Даже исправление SQL 2016 будет основываться на человеческих вмешательствах и обновлениях правил, которые будут продолжаться, поскольку разные страны, штаты и города вносят изменения в свои законы о летнее время. UTC - это самый надежный и надежный инструмент в вашем распоряжении.

+0

Это то, о чем я могу договориться. К сожалению, с нашим программным обеспечением мы имеем представление о том, что все время хранится в нашей базе данных с использованием Локального времени ... Поэтому изменить это на UTC было бы непростой задачей. – Nathan24

+0

@ Натан, это несчастливо. Это ситуация, когда вы можете просматривать информацию по дереву ответственности и делать это чужой проблемой? Или, по крайней мере, сообщите им, что даже при обновлении сервера и сложных функциях метод nonUTC будет «очень хорошим». – Forklift

+0

Да, я не могу сделать это чужой проблемой. Я обязан определить то, что мы можем исправить, прежде чем DST начнется в марте. К счастью, большинство наших клиентов работают на базе US Based, и я могу просто добавить флаг переопределения для клиентов в Аризоне или других подобных местах, которые не соблюдают DST. Но похоже, что мне просто нужно пойти с параметром «Довольно хорошо», и это позволит мне в будущем привести аргумент для рефакторинга в метод UTC. – Nathan24