우리는 다른 시간대와 일광 절약 시간 설정의 글로벌 시간 데이터를 처리해야하는 응용 프로그램을 다루고 있습니다. 아이디어는 내부적으로 모든 것을 UTC 형식으로 저장하고 지역화 된 사용자 인터페이스에 대해서만 앞뒤로 변환하는 것입니다. SQL Server는 시간, 국가 및 시간대가 지정된 번역을 처리하기위한 메커니즘을 제공합니까?
이것은 일반적인 문제 일 것이므로 Google이 사용할 수있는 항목을 표시하지 않을 것이라는 점에 놀랐습니다.
포인터가 있습니까?
답변
7 년이 지났고
실제로 필요한 작업을 정확히 수행하는 새로운 SQL Server 2016 기능이 있습니다.
AT TIME ZONE이라고하며 서머 타임 (DST) 변경을 고려하여 날짜를 지정된 시간대로 변환합니다.
자세한 정보 :
https://msdn.microsoft.com/en-us/library/mt612795.aspx
답변
이것은 현재 SQL Server의 호스트와 동일한 UTC 오프셋을 가진 날짜에 대해 작동합니다. 일광 절약 시간 변경을 고려하지 않습니다. YOUR_DATE
변환 할 현지 날짜로 바꿉니다 .
SELECT DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), YOUR_DATE);
답변
이러한 답변 중 몇 가지가 당신을 구장에 가져다 줄 것이지만, 일광 절약 시간 때문에 SqlServer 2005 및 이전 버전에 대해 임의의 날짜로하려는 작업을 수행 할 수 없습니다. 현재 로컬과 현재 UTC의 차이를 사용하면 현재 존재하는 오프셋을 얻을 수 있습니다. 문제의 날짜에 대해 오프셋이 무엇 이었을지 결정하는 방법을 찾지 못했습니다.
즉, SqlServer 2008이이 문제를 해결할 수있는 몇 가지 새로운 날짜 기능을 제공한다는 것을 알고 있지만 이전 버전을 사용하는 사람들은 제한 사항을 알고 있어야합니다.
우리의 접근 방식은 UTC를 유지하고 변환의 정확성을 더 많이 제어 할 수있는 클라이언트 측에서 변환을 수행하는 것입니다.
답변
SQL Server 2016 이상 및 Azure SQL Database의 경우 기본 제공 AT TIME ZONE
문을 사용합니다 .
이전 버전의 SQL Server의 경우 SQL Server 표준 시간대 지원 프로젝트를 사용하여 여기에 나열된대로 IANA 표준 표준 시간대간에 변환 할 수 있습니다 .
UTC to Local은 다음과 같습니다.
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'America/Los_Angeles')
로컬에서 UTC는 다음과 같습니다.
SELECT Tzdb.LocalToUtc('2015-07-01 00:00:00', 'America/Los_Angeles', 1, 1)
숫자 옵션은 현지 시간 값이 일광 절약 시간의 영향을받는 경우 동작을 제어하기위한 플래그입니다. 이것들은 프로젝트 문서에 자세히 설명되어 있습니다.
답변
SQL Server 2008에는 datetimeoffset
. 이런 종류의 물건에 정말 유용합니다.
http://msdn.microsoft.com/en-us/library/bb630289.aspx
그런 다음 함수 SWITCHOFFSET
를 사용하여 한 시간대에서 다른 시간대로 이동할 수 있지만 여전히 동일한 UTC 값을 유지합니다.
http://msdn.microsoft.com/en-us/library/bb677244.aspx
Rob
답변
다음은 한 영역 DateTime
을 다른 영역 으로 변환하는 코드입니다.DateTime
DECLARE @UTCDateTime DATETIME = GETUTCDATE();
DECLARE @ConvertedZoneDateTime DATETIME;
-- 'UTC' to 'India Standard Time' DATETIME
SET @ConvertedZoneDateTime = @UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE 'India Standard Time'
SELECT @UTCDateTime AS UTCDATE,@ConvertedZoneDateTime AS IndiaStandardTime
-- 'India Standard Time' to 'UTC' DATETIME
SET @UTCDateTime = @ConvertedZoneDateTime AT TIME ZONE 'India Standard Time' AT TIME ZONE 'UTC'
SELECT @ConvertedZoneDateTime AS IndiaStandardTime,@UTCDateTime AS UTCDATE
참고 : AT TIME ZONE
SQL Server 2016+에서만 작동 하며 특정 시간대로 변환 할 때 자동으로 일광을 고려 한다는 장점이 있습니다.
답변
나는 지역 이벤트 (예 : 회의 / 파티 등, 박물관에서 12 pm-3pm)와 관련이없는 모든 날짜-시간 저장소에 DateTimeOffset을 사용하는 경향이 있습니다.
현재 DTO를 UTC로 가져 오려면 :
DECLARE @utcNow DATETIMEOFFSET = CONVERT(DATETIMEOFFSET, SYSUTCDATETIME())
DECLARE @utcToday DATE = CONVERT(DATE, @utcNow);
DECLARE @utcTomorrow DATE = DATEADD(D, 1, @utcNow);
SELECT @utcToday [today]
,@utcTomorrow [tomorrow]
,@utcNow [utcNow]
참고 : 유선으로 전송할 때 항상 UTC를 사용합니다. 클라이언트 측 JS는 로컬 UTC에 쉽게 접근 할 수 있습니다. 참조 : new Date().toJSON()
…
다음 JS는 ISO8601 형식의 UTC / GMT 날짜를 로컬 datetime으로 구문 분석합니다.
if (typeof Date.fromISOString != 'function') {
//method to handle conversion from an ISO-8601 style string to a Date object
// Date.fromISOString("2009-07-03T16:09:45Z")
// Fri Jul 03 2009 09:09:45 GMT-0700
Date.fromISOString = function(input) {
var date = new Date(input); //EcmaScript5 includes ISO-8601 style parsing
if (!isNaN(date)) return date;
//early shorting of invalid input
if (typeof input !== "string" || input.length < 10 || input.length > 40) return null;
var iso8601Format = /^(\d{4})-(\d{2})-(\d{2})((([T ](\d{2}):(\d{2})(:(\d{2})(\.(\d{1,12}))?)?)?)?)?([Zz]|([-+])(\d{2})\:?(\d{2}))?$/;
//normalize input
var input = input.toString().replace(/^\s+/,'').replace(/\s+$/,'');
if (!iso8601Format.test(input))
return null; //invalid format
var d = input.match(iso8601Format);
var offset = 0;
date = new Date(+d[1], +d[2]-1, +d[3], +d[7] || 0, +d[8] || 0, +d[10] || 0, Math.round(+("0." + (d[12] || 0)) * 1000));
//use specified offset
if (d[13] == 'Z') offset = 0-date.getTimezoneOffset();
else if (d[13]) offset = ((parseInt(d[15],10) * 60) + (parseInt(d[16],10)) * ((d[14] == '-') ? 1 : -1)) - date.getTimezoneOffset();
date.setTime(date.getTime() + (offset * 60000));
if (date.getTime() <= new Date(-62135571600000).getTime()) // CLR DateTime.MinValue
return null;
return date;
};
}