SQL Server에서 TimeZone을 올바르게 처리하는 방법은 무엇입니까?


34

내 로컬 개발 서버는 중동에 있지만 프로덕션 서버는 영국에 있습니다.

시간대로 사용자에게 날짜를 표시해야합니다. 예를 들어, 사용자가 사우디 아라비아 인 경우 사우디 아라비아 형식에 따라 시간을 표시해야합니다.

TimeZone이라는 새 데이터베이스 테이블을 만들고 UTC로 시간을 저장해야합니까?


효과적으로 UTC와 로컬 SQL 2005에서 (예. PST) 시간과 날짜 변환 http://stackoverflow.com/questions/24797/effectively-converting-dates-between-utc-and-local-ie-pst-time-in-을 sql-2005
mehdi

이것은 웹 응용 프로그램입니까, 아니면 데스크톱 응용 프로그램입니까, 아니면 ...입니까? 이것이 구현되는 방법은 클라이언트 전달 메커니즘에 따라 다릅니다. 필요한 것은 클라이언트 측에 달려 있기 때문입니다.
Jon Seigel

이 웹 및 기본 모바일. 예,이 효과는 고객마다 다릅니다.
user960567

1
귀하의 질문은 데이터베이스 자체에 관한 것이 아니라 응용 프로그램 개발과 관련이있는 것 같습니다. 이 스택 오버플로 질문은 다음에 꼭 읽어야합니다. 일광 절약 시간제 및 시간대 모범 사례
Gan

답변:


47

불행히도이 문제에 대한 빠른 해결책은 없습니다. 응용 프로그램의 국제화는 날짜 / 시간 비교 및 ​​출력 형식을 포함하여 다양한 영역의 핵심으로 이동하기 때문에 최초의 디자인 토론의 일부가되어야합니다.

어쨌든, Doing It Right를 추적하려면 시간대 정보 를 시간과 함께 저장해야합니다 . 즉, 날짜 / 시간을 실현 20130407 14:50하다 의미 없는 시간대의 오프셋 당시 UTC 포함 하나 (a) (주 1) 모든 로직 먼저 변환을 이들 값을 삽입하는 것을 보장하거나, (b) 소정의 고정 된 오프셋 ( 대부분 0). 두 가지 중 하나가 없으면 두 개의 주어진 시간 값을 비교할 수 없으며 데이터가 손상 됩니다. (후자의 방법은 불을 가지고 노는 것입니다 (주 2) . 그렇지 마십시오.)

SQL Server 2008+에서는 datetimeoffset데이터 형식 을 사용하여 시간과 함께 오프셋을 직접 저장할 수 있습니다 . (완전성을 위해 2005 년과 그 이전에는 당시의 UTC 오프셋 값 (분)을 저장하는 두 번째 열을 추가합니다.)

이러한 플랫폼에는 일반적으로 날짜 / 시간 + 시간대를 현지 시간으로 자동 변환 한 다음 출력 형식을 지정할 수있는 메커니즘이있어 사용자의 국가 별 설정에 따라 데스크톱 유형 응용 프로그램에서 쉽게 사용할 수 있습니다.

본질적으로 연결이 끊긴 아키텍처 인 웹의 경우 백엔드 데이터가 올바르게 설정되어 있어도 변환 및 / 또는 서식을 수행하려면 클라이언트에 대한 정보가 필요하기 때문에 더 복잡합니다. 이것은 일반적으로 사용자 기본 설정 (출력 전에 응용 프로그램이 변환 / 형식화)을 통해 수행되거나 모든 사람에 대해 동일한 고정 형식 및 표준 시간대 오프셋을 사용하여 표시합니다 (스택 교환 플랫폼이 현재 수행하는 작업).

백엔드 데이터가 올바르게 설정되지 않은 경우 매우 신속하고 복잡해집니다. 나는 그 길을 내려가는 것을 권장하지 않을 것입니다.

참고 1 :

시간대의 UTC 오프셋은 고정되어 있지 않습니다. 시간대의 UTC 오프셋이 1 시간 더하기 또는 빼기에 따라 일광 절약 시간제를 고려하십시오. 또한 영역의 일광 절약 시간은 정기적으로 다릅니다. 따라서 datetimeoffset(또는 복합 local timeUTC offset at that time)을 사용하면 정보 복구가 극대화됩니다.

노트 2:

데이터 입력 제어에 관한 것입니다. 들어오는 값을 확인하는 완벽한 방법은 없지만 계산을 포함하지 않는 간단한 표준을 적용하는 것이 좋습니다. 퍼블릭 API가 오프셋을 포함하는 데이터 유형을 예상하면 해당 요구 사항은 호출자에게 분명합니다.

그렇지 않은 경우 호출자는 문서에 의존해야하거나 (읽은 경우) 계산이 잘못 수행됩니다. 특히 분산 시스템의 경우 오프셋을 요구할 때 실패 / 버그 모드가 줄어 듭니다 ( 또는 별도의 서버에있는 웹 / 데이터베이스 만 여기에 해당합니다).

어쨌든 오프셋을 저장하면 하나의 돌로 두 마리의 새가 죽습니다. 지금 필요하지 않더라도 나중에 필요할 경우 사용할 수 있습니다. 실제로 더 많은 스토리지를 차지하지만 데이터가 처음에 기록되지 않으면 데이터가 손실되므로 트레이드 오프 가치가 있다고 생각합니다.


3
내가 알기로 오프셋은 표준 시간대와 동일하지 않습니다 ... datetimeoffset에 저장된 시간은 일광 절약 시간 인식과 같은 정보를 잃어 버립니다 ... 추가 정보 : stackoverflow.com/tags/timezone/info
Peter McEvoy

1
@PeterMcEvoy DST는 여기에 관련이 없습니다. datetimeoffset"이것은 사건이 발생한 사용자 / 컴퓨터의 현지 시간"을 의미합니다. 주어진 UTC 오프셋이 항상 존재하기 때문에 DST가 적용되었는지 여부를 알 필요가 없습니다 ( datetimeoffset값에 포함).
다이

12

SQL Server에서 표준 시간대 변환을위한 포괄적 인 솔루션을 개발했습니다. GitHub에서 SQL Server 표준 시간대 지원을 참조하십시오 .

일광 절약 시간을 포함하여 표준 시간대와 UTC 간의 변환을 올바르게 처리합니다.

광고 답변에 설명 된 "T-SQL Toolbox"솔루션과 개념 상 유사하지만 Microsoft 대신에 더 일반적인 IANA / Olson / TZDB 시간대를 사용하며, 데이터를 최신 버전으로 유지 관리하는 유틸리티를 포함합니다. TZDB가 나옵니다.

사용법 예 (OP에 응답하기 위해) :

SELECT Tzdb.UtcToLocal(sysutcdatetime(), 'Asia/Riyadh') as CurrentTimeInSaudiArabia

추가 API 및 자세한 설명 은 GitHub 추가 정보를 참조하십시오 .

또한이 솔루션은 UDF 기반 솔루션이므로 성능이 기본 목표로 설계되지 않았습니다. 이 기능이 CONVERT_TZOracle 및 MySQL에 존재 하는 방식과 유사하게이 기능이 SQL Server에 내장되어 있으면 더 좋습니다 .


6

SQL Server는 2005 년부터 내부 시간대가 UTC로 저장된 위치에서 수정되었습니다. 이는 주로 로그 전달과 관련된 지역 복제 및 HA 프로젝터 때문이며 다른 시간대로 로그 전달 시간을 저장하면 기존 방법으로 복원 할 수 없었습니다.

따라서 모든 것을 내부적으로 UTC 시간으로 저장하면 SQL Server가 전 세계적으로 잘 작동 할 수있었습니다. Outlook과 같은 다른 MS 제품도 내부적으로 날짜 / 시간을 UTC로 저장하고 패치해야하는 오프셋을 만들기 때문에 일광 절약 시간이 Windows에서 처리하기 어려운 이유 중 하나입니다.

전 세계에 수천 대의 서버 (MS SQL Server는 아니지만 모든 종류의 서버)가 퍼져있는 회사에서 일하고 있습니다. 매우 빠르게.


5

SQL Server에서 날짜 시간 및 표준 시간대 처리에 어려움 을 겪는 사람을 돕기 위해 codeplex 에서“T-SQL Toolbox”프로젝트 개발하고 게시했습니다 . 오픈 소스이며 완전 무료입니다.

별도의 구성 테이블과 함께 일반 T-SQL을 사용하여 쉬운 날짜 / 시간 변환 UDF를 제공합니다.

귀하의 예에서 다음 샘플을 사용할 수 있습니다.

SELECT [DateTimeUtil].[UDF_ConvertLocalToLocalByTimezoneIdentifier] (
    'GMT Standard Time', -- the original timezone in which your datetime is stored
    'Middle East Standard Time', -- the target timezone for your user
    '2014-03-30 01:55:00' -- the original datetime you want to convert
)

사용자의 변환 된 날짜 / 시간 값을 반환합니다.

지원되는 모든 시간대 목록은 T-SQL Toolbox 데이터베이스의 "DateTimeUtil.Timezone"테이블에서도 확인할 수 있습니다.


이러한 툴킷은 개발자에게 큰 도움이 될 것 같습니다. 그러나 스칼라 함수는 쿼리 최적화 프로그램의 블랙 박스입니다. 그것은 함수를 열에 적용 할 때 언급 한 구성 테이블이 결과 세트에 행이있는 횟수만큼 적중한다는 것을 의미합니다 (SELECT 절에서만 함수를 사용한다고 가정). 성능 측면에서 좋은 관점은 아닙니다. 나는 실제로 툴킷을 테스트하지 않았으므로 확실하게 말할 수는 없다. 그것은 내가 아는 것에 기초한 일반적인 관심사 일 뿐이다.
Andriy M

Andriy는 성능 측면에서 옳습니다. UDF 조회 테이블은 대량 데이터 조작이 아니라 사용이 용이하도록 설계되었습니다. 그럼에도 불구하고 그들은 내 컴퓨터에서 최대 약 100.000 레코드를 수행합니다.
광고 at

2
유스 케이스에서 더 많은 레코드를 처리해야하고 성능이 중요한 경우 사전 계산 된 데이터를 유지하는 것이 좋습니다. 그러나 이러한 UDF는 필요한 팀 영역에서 데이터 시간 값을 유지하는 데 도움이 될 수 있습니다.
광고

내 관점에서이 문제는 성능에 관한 것이 아니라 기본 기능을 얻는 것에 관한 것입니다. 쿼리에서 정확한 정보를 반환 할 수 있어야합니다. 캐시하기 위해 임시 테이블을 작업 한 다음 쿼리에서 해당 테이블을 참조하거나 성능을 향상시키기 위해 처리합니다.
액션 댄

1

나는 명백한 것을 놓칠 수도 있지만, 사용자 시간대와 언어 형식을 사용하여 날짜를 표시하는 것이라면 가장 간단한 방법은 항상 날짜를 데이터베이스에 UTC로 저장하고 클라이언트 응용 프로그램을 UTC에서 로컬로 변환하는 것입니다 시간대를 설정하고 사용자 지역 설정을 사용하여 날짜를 적절하게 형식화합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.