2011-09-26 3 views
2

GMT 타임 스탬프 이벤트를 사용하여 데이터베이스 (SQL Server 2005,하지만 제 질문은 더 일반적인 것 같습니다)가 있습니다. 여러 가지 이유로 사용자의 로컬 시간을 기준으로 데이터를 쿼리하고 집계 할 수 있어야합니다. 예를 들어 현지 시간으로 오후 5시에서 7시 사이에 몇 번이나 이벤트가 발생 했습니까? DST는 정말이 하나에 대한 루프에 나를 던지고있다.현지 시간별 이벤트 쿼리

나는 모든 시간대/dst 규칙의 테이블을 유지하려고 노력했다. 그런 다음 결과 테이블을 사용자의 시간대/표준 시간대 정보로 제한하여 이벤트 테이블에 가입 할 수 있습니다. 이 DST 테이블을 것 가능성이 유지 보수 악몽이 될 것보다처럼 보인다

select count(e.ID) 
from events e 
    join dst d on e.timeGMT between d.startGMT and d.endGMT 
where [email protected] 
    and dbo.getTime(dateadd(ss, d.offsetSec, e.timeGMT)) between '17:00' and '19:00' 

: 그래서 내 예를 들어 쿼리 같이 보일 것입니다. 그럼 누구 한테 더 나은 선택권이 있니?

는 UPDATE 글쎄, 내 질문에 약간의 혼동이있을 것 같습니다, 그래서 DST는 2시 현지 시간으로 미국에서 끝나는 ...

첫째,주의 좀 샘플 데이터를 제공합니다 일요일, 11 월 6 일.

내가 다음과 같은 결과를 얻는 좋은 방법을 찾고 있어요 이벤트

create table events(ID int, timeGMT datetime) 

insert into events(ID, timeGMT) 
select 1, '2011-11-04 20:00' union --16:00 EDT 
select 2, '2011-11-04 20:15' union --16:15 EDT 
select 3, '2011-11-04 20:30' union --16:30 EDT 
select 4, '2011-11-04 20:45' union --16:45 EDT 
select 5, '2011-11-04 21:00' union --17:00 EDT 
select 6, '2011-11-04 21:15' union --17:15 EDT 
select 7, '2011-11-04 21:30' union --17:30 EDT 
select 8, '2011-11-04 21:45' union --17:45 EDT 
select 9, '2011-11-04 22:00' union --18:00 EDT 
select 10, '2011-11-04 22:15' union --18:15 EDT 
select 11, '2011-11-04 22:30' union --18:30 EDT 
select 12, '2011-11-04 22:45' union --18:45 EDT 
select 13, '2011-11-04 23:00' union --19:00 EDT 
select 14, '2011-11-06 20:00' union --15:00 EST 
select 15, '2011-11-06 20:15' union --15:15 EST 
select 16, '2011-11-06 20:30' union --15:30 EST 
select 17, '2011-11-06 20:45' union --15:45 EST 
select 18, '2011-11-06 21:00' union --16:00 EST 
select 19, '2011-11-06 21:15' union --16:15 EST 
select 20, '2011-11-06 21:30' union --16:30 EST 
select 21, '2011-11-06 21:45' union --16:45 EST 
select 22, '2011-11-06 22:00' union --17:00 EST 
select 23, '2011-11-06 22:15' union --17:15 EST 
select 24, '2011-11-06 22:30' union --17:30 EST 
select 25, '2011-11-06 22:45' union --17:45 EST 
select 26, '2011-11-06 23:00'  --18:00 EST 

의 주어진 다음의 표. 현지 시작 시간 17:00, 현지 종료 시간 18:00 및 현지 시간대 US-Easter가 제공된다고 가정하십시오.

ID | timeGMT 
----|------------------ 
    5 | 2011-11-04 21:00 
    6 | 2011-11-04 21:15 
    7 | 2011-11-04 21:30 
    8 | 2011-11-04 21:45 
    9 | 2011-11-04 22:00 
22 | 2011-11-06 22:00 
23 | 2011-11-06 22:15 
24 | 2011-11-06 22:30 
25 | 2011-11-06 22:45 
26 | 2011-11-06 23:00 

또한 실제 세트의 DST 규칙과 모든 시간대에서 작동하기를 원합니다. 실제 데이터 집합이 몇 년에 걸친다는 사실을 포함하여 몇 가지 DST 변경이 포함됩니다.

업데이트 2 기본적으로 원래 설명한 솔루션을 구현했지만 필요한 유지 관리 작업을 대폭 줄이는 코드도 만들었습니다.

  1. 는 내가 걱정 연도의 모든 영역에 대한 변화를 상쇄 모든 GMT의 목록을 출력 (here 가능한 일명.은 zoneinfo, IANA 시간대, 또는 올슨 데이터베이스)를 TZ 데이터베이스를 구문 분석합니다.
  2. 목록을 임시 테이블에 삽입하십시오.
  3. 임시 테이블을 사용하여 각 GMT 오프셋에 대한 각 영역의 시간 범위를 만듭니다.

답변

0

글쎄, 당신은 할 수 있음을 단지 작은 아이디어 고려 :

를 대신 쿼리시 테이블 (들)의 데이터를 변환, 당신은 논리를 반전 대신 사용자의 로컬 시간으로 변환 할 수 있습니다 범위 매개 변수를 GMT로 변환 한 다음 GMT로 모든 것을 수행합니다. 결과를 현지 시간으로 되돌리려면 그 시점에서 다시 변환 할 수 있습니다.

이것이 효과적인 해결책인지 여부는 쿼리의 성격에 따라 다릅니다.

+0

, 난 당신이 여기에 문제의 핵심을 놓치고 생각합니다. 여러 DST 교대를 어떻게 처리합니까? 사용자는 DST 시작/종료 시점을 기억해야합니까? – chezy525

0

이러한 상황에서 우리는 일반적으로 현재 GMT 시간에 전달하는 앞에서이 절차를 호출하면 System.DateTime.UtcNow를 사용하여이 방법을 사용하여 데이터를 비교합니다. SQL Server에서 datetime 변환을 수행해야합니다.

편집 : 나는이 일반적으로 당신과 동의하지만

declare @table table(eventName Varchar(50), [time] time) 
    insert into @table(eventName, [time]) Values ('event 1', '03:30') 
    insert into @table(eventName, [time]) Values ('event 1', '04:00') 
    insert into @table(eventName, [time]) Values ('event 2', '04:20') 
    insert into @table(eventName, [time]) Values ('event 3', '05:20') 
    insert into @table(eventName, [time]) Values ('event 3', '07:20') 

    select * from @table 

    -- assuming ur local time is +1 GMT 
    declare 
     @timeFromLocal time = '05:00', 
     @timeToLocal time = '07:00', 
     @timeFromGMT time, 
     @timeToGMT time, 
     @Offset int = -1 

    /*I prefer doing the following conversion from the front end where the time reflects the users time zone*/ 
    set @timeFromGMT = DATEADD(Hour, @Offset, @timeFromLocal) 
    set @timeToGMT = DATEADD(Hour, @Offset, @timeToLocal) 

    select * from @table Where [time] between @timeFromGMT and @timeToGMT 
+0

이것은 여러 DST 교대 시간에 대한 로컬 시간의 이벤트를 쿼리하지 못합니다. – chezy525

+0

위의 상황에서는 현지 시간 오후 5시에서 오후 7시 사이에 이벤트가 필요하므로 프런트 엔드에서 해당 시간으로 변환 한 다음 프로 시저로 전달합니다. 데이터베이스에서 이러한 gmt 시간 사이에 있는지 확인해야합니다. –

+0

내 첫 번째 의견은 여전히 ​​유효합니다. 이벤트에 하나 이상의 DST 교대에 걸쳐 전체 datetime 값이있는 경우 해당 DST 교대에 대해 GMT 조정이 필요합니다. 이 경우에는 해당되지 않습니다. – chezy525