select 문의 Datetime 열을 UTC에서 로컬 시간으로 변환
SQL 선택 쿼리를 몇 개 실행하고 있으며 UTC datetime 열을 로컬 시간으로 변환하여 쿼리 결과에 로컬 시간으로 표시하려고 합니다.코드로 변환하는 것이 아니라 데이터베이스에 대해 수동 및 랜덤 SQL 쿼리를 수행할 때 변환하려고 합니다.
SQL Server 2008 이상에서는 다음과 같이 수행할 수 있습니다.
SELECT CONVERT(datetime,
SWITCHOFFSET(CONVERT(datetimeoffset,
MyTable.UtcColumn),
DATENAME(TzOffset, SYSDATETIMEOFFSET())))
AS ColumnInLocalTime
FROM MyTable
또한 보다 적은 세부사항을 수행할 수도 있습니다.
SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), MyTable.UtcColumn)
AS ColumnInLocalTime
FROM MyTable
무슨 일이 있어도 사용하지 마세요.-날짜를 빼는 것은 연산이 원자적이지 않고 시스템 날짜 시간과 로컬 날짜 시간 사이의 레이스 조건이 서로 다른 시간(즉, 비원자적)에 확인되기 때문에 때때로 불확실한 결과를 얻을 수 있기 때문입니다.
이 답변에서는 DST는 고려되지 않습니다.DST 조정을 포함할 경우 다음 SO 질문도 참조하십시오.
SQL Server에서 여름 시간 시작 및 종료 함수를 만드는 방법
UTC로 저장된 날짜/시간을 지정된 시간대(Azure SQL 데이터베이스가 UTC로 실행되므로 서버의 시간대가 아님)로 만드는 데 도움이 되지 않는 예시를 발견했습니다.난 이렇게 처리했어우아하지는 않지만 심플하고 다른 표를 유지하지 않고도 올바른 답을 얻을 수 있습니다.
select CONVERT(datetime, SWITCHOFFSET(dateTimeField, DATEPART(TZOFFSET,
dateTimeField AT TIME ZONE 'Eastern Standard Time')))
날짜 이 "Date Time"인 경우Eastern Standard TimeUTC: Azure SQL: SQL Server 2016: UTC: Azure SQL: Azure SQL: SQL Server 2016: Azure Server: UTC: Azure SQL: Azure SQL: SQL Server 2016.
SELECT YourUtcColumn AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time' AS
LocalTime
FROM YourTable
시간대 이름의 전체 목록은 다음과 같이 확인할 수 있습니다.
SELECT * FROM sys.time_zone_info
그리고 그렇다, 타임존의 이름은 좋지 않다 - 비록 그렇다 하더라도Eastern Standard Time
서버의 위치 이외의 변환이 필요한 경우는, 표준 오프셋을 건네고 US Summer Savings Times 를 어카운트 할 수 있는 함수를 다음에 나타냅니다.
-- =============================================
-- Author: Ron Smith
-- Create date: 2013-10-23
-- Description: Converts UTC to DST
-- based on passed Standard offset
-- =============================================
CREATE FUNCTION [dbo].[fn_UTC_to_DST]
(
@UTC datetime,
@StandardOffset int
)
RETURNS datetime
AS
BEGIN
declare
@DST datetime,
@SSM datetime, -- Second Sunday in March
@FSN datetime -- First Sunday in November
-- get DST Range
set @SSM = datename(year,@UTC) + '0314'
set @SSM = dateadd(hour,2,dateadd(day,datepart(dw,@SSM)*-1+1,@SSM))
set @FSN = datename(year,@UTC) + '1107'
set @FSN = dateadd(second,-1,dateadd(hour,2,dateadd(day,datepart(dw,@FSN)*-1+1,@FSN)))
-- add an hour to @StandardOffset if @UTC is in DST range
if @UTC between @SSM and @FSN
set @StandardOffset = @StandardOffset + 1
-- convert to DST
set @DST = dateadd(hour,@StandardOffset,@UTC)
-- return converted datetime
return @DST
END
GO
새로운 SQL Server 2016 기회 활용:
CREATE FUNCTION ToLocalTime(@dtUtc datetime, @timezoneId nvarchar(256))
RETURNS datetime
AS BEGIN
return @dtUtc AT TIME ZONE 'UTC' AT TIME ZONE @timezoneId
/* -- second way, faster
return SWITCHOFFSET(@dtUtc , DATENAME(tz, @dtUtc AT TIME ZONE @timezoneId))
*/
/* -- third way
declare @dtLocal datetimeoffset
set @dtLocal = @dtUtc AT TIME ZONE @timezoneId
return dateadd(minute, DATEPART (TZoffset, @dtLocal), @dtUtc)
*/
END
GO
단, clr 프로시저는 5배 고속으로 동작합니다.- (
1개의 TimeZone 오프셋은 겨울 또는 여름 시간으로 변경될 수 있습니다.예를들면
select cast('2017-02-08 09:00:00.000' as datetime) AT TIME ZONE 'Eastern Standard Time'
select cast('2017-08-08 09:00:00.000' as datetime) AT TIME ZONE 'Eastern Standard Time'
결과:
2017-02-08 09:00:00.000 -05:00
2017-08-08 09:00:00.000 -04:00
상수 간격띄우기만 추가할 수는 없습니다.
SQL 서버의 타임존을 사용하는 것 외에 데이터베이스에서 CLR을 활성화하는 것이 옵션인 경우 에 기술할 수 있습니다.넷은 꽤 간단하다.
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlDateTime fn_GetLocalFromUTC(SqlDateTime UTC)
{
if (UTC.IsNull)
return UTC;
return new SqlDateTime(UTC.Value.ToLocalTime());
}
}
UTC datetime 값이 입력되고 서버에 상대적인 로컬 datetime 값이 출력됩니다.null 값은 null을 반환합니다.
이것들 중 어느 것도 나에게는 효과가 없었지만, 아래의 것은 100% 효과가 있었다.이게 다른 사람들이 나처럼 바꾸려고 하는 데 도움이 되길 바라.
CREATE FUNCTION [dbo].[fn_UTC_to_EST]
(
@UTC datetime,
@StandardOffset int
)
RETURNS datetime
AS
BEGIN
declare
@DST datetime,
@SSM datetime, -- Second Sunday in March
@FSN datetime -- First Sunday in November
-- get DST Range
set @SSM = DATEADD(dd,7 + (6-(DATEDIFF(dd,0,DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 2,0))%7)),DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 2,0))+'02:00:00'
set @FSN = DATEADD(dd, (6-(DATEDIFF(dd,0,DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 10,0))%7)),DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 10,0)) +'02:00:00'
-- add an hour to @StandardOffset if @UTC is in DST range
if @UTC between @SSM and @FSN
set @StandardOffset = @StandardOffset + 1
-- convert to DST
set @DST = dateadd(hour,@StandardOffset,@UTC)
-- return converted datetime
return @DST
END
데이터를 UTC 날짜로 데이터베이스에 저장하면 다음과 같은 간단한 작업을 수행할 수 있습니다.
select
[MyUtcDate] + getdate() - getutcdate()
from [dbo].[mytable]
이며, 일은 .TIME ZONE 'your time zone name'클라이언트의 인스톨과 같이 데이터베이스가 다른 타임 존으로 이동하면, 하드 코드화된 타임 존에 감염될 가능성이 있습니다.
가장 쉬운 답은 항상 맨 아래쪽에 있는 것은 아니지만, 이번에는 맨 아래이며, 위의 댓글에 이미 숨겨져 있는 어딘가에서 볼 수 있습니다.현재 SYSDATETIME 필드가 아닌 자신의 'AT TIME ZONE'을 사용하여 TzOffset을 캡처합니다.아래 데이터에서는 2개의 쿼리, 2개의 쿼리(DST는 오프, 암스테르담의 윈터) +1 diff, 두 번째 쿼리는 암스테르담의 4월 데이터에 대해 +2시간 차이입니다.
select top 2 month(receiveTimeUTC) as MonthInWinterOrSpring
, receiveTimeUTC
, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, receiveTimeUTC), DATENAME(TzOffset, SYSDATETIMEOFFSET()))) as LocalTimeWrongNoDST
, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, receiveTimeUTC), DATENAME(TzOffset, receiveTimeUTC AT TIME ZONE 'Central European Standard Time' ))) as LocalTimeWithDST
from sensordetails order by id
select top 2 month(receiveTimeUTC) as MonthInWinterOrSpring, receiveTimeUTC
, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, receiveTimeUTC), DATENAME(TzOffset, SYSDATETIMEOFFSET()))) as LocalTimeWrongNoDST
, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, receiveTimeUTC), DATENAME(TzOffset, receiveTimeUTC AT TIME ZONE 'Central European Standard Time' ))) as LocalTimeWithDST
from sensordetails order by id desc
결과:
이것은 T-SQL(SQL Server Answer)이며, 저장 프로시저가 필요하지 않습니다.
이것을 올바르고 일반적인 방법으로 하는 간단한 방법은 없습니다.
DST에.GetDate()-GetUTCDate는 서버의 TZ에서 현재 오프셋만 제공되며, 이는 관련이 없습니다.
저는 두 가지 솔루션만 보았고 많이 검색했습니다.
1) TZ당 표준 시간대 및 DST 규칙 등의 기본 데이터 테이블이 몇 개 있는 커스텀 SQL 함수.일을 하고 있지만 우아하지는 않다.코드가 없어서 올릴 수가 없어요.
편집: 다음은 이 방법의 예입니다.https://gist.github.com/drumsta/16b79cee6bc195cd89c8
2) .net 어셈블리를 db 에 추가합니다.넷은 이것을 매우 쉽게 할 수 있다.이 방법은 매우 잘 동작하지만 단점은 서버 레벨에서 몇 가지 파라미터를 설정해야 한다는 것입니다.또한 데이터베이스를 복원하는 등 설정이 쉽게 파손됩니다.저는 이 방법을 사용하지만 코드가 없어서 게시할 수 없습니다.
이 함수는 DST 조정을 통해 UTC 시간을 EST 시간으로 변환합니다.이 함수로 설계한 시간대 이름을 변경하거나 레지스트리에서 가져올 수 있습니다.
Create Function fnConvertUTCTimetoESTTime(
@UTCTime as datetime
)
returns datetime
as
begin
return convert(datetime, convert(varchar(23), @UTCTime AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time', 121), 121)
end
go
select dbo.fnConvertUTCTimetoESTTime ('2020-3-8 5:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-3-8 6:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-3-8 7:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-3-8 8:00:00.000')
--returns 0:00am, 1:00am, 3:00am, 4:00am
select dbo.fnConvertUTCTimetoESTTime ('2020-11-1 4:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-11-1 5:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-11-1 6:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-11-1 7:00:00.000')
--returns 0:00am, 1:00am, 1:00am, 2:00am
이 결과는 실제로는 EST 형식의 UTC 시간이므로 "@UTCime AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'" 결과를 반환할 수 없습니다(이 "짝퉁" EST 시간을 비교하거나 절에 포함하면 UTC 시간으로 다시 변환됩니다).
및 Azure SQL의 »@@Version>= SQL Server 2016 사용자 아래는 를 사용한 간단한 기능입니다.
CREATE FUNCTION [dbo].[Global_Convert_UTCTimeTo_LocalTime]
(
@LocalTimeZone VARCHAR(50),
@UTCDateTime DATETIME
)
RETURNS DATETIME
AS
BEGIN
DECLARE @ConvertedDateTime DATETIME;
SELECT @ConvertedDateTime = @UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE @LocalTimeZone
RETURN @ConvertedDateTime
END
GO
다음과 같은 값 유형의 경우@LocalTimeZone이 링크로 이동하거나 다음 링크로 이동하세요.KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
다음은 여름 시간, UTC 오프셋을 고려하여 특정 연도에 잠겨 있지 않은 버전입니다.
---------------------------------------------------------------------------------------------------
--Name: udfToLocalTime.sql
--Purpose: To convert UTC to local US time accounting for DST
--Author: Patrick Slesicki
--Date: 3/25/2014
--Notes: Works on SQL Server 2008R2 and later, maybe SQL Server 2008 as well.
-- Good only for US States observing the Energy Policy Act of 2005.
-- Function doesn't apply for years prior to 2007.
-- Function assumes that the 1st day of the week is Sunday.
--Tests:
-- SELECT dbo.udfToLocalTime('2014-03-09 9:00', DEFAULT)
-- SELECT dbo.udfToLocalTime('2014-03-09 10:00', DEFAULT)
-- SELECT dbo.udfToLocalTime('2014-11-02 8:00', DEFAULT)
-- SELECT dbo.udfToLocalTime('2014-11-02 9:00', DEFAULT)
---------------------------------------------------------------------------------------------------
ALTER FUNCTION udfToLocalTime
(
@UtcDateTime AS DATETIME
,@UtcOffset AS INT = -8 --PST
)
RETURNS DATETIME
AS
BEGIN
DECLARE
@PstDateTime AS DATETIME
,@Year AS CHAR(4)
,@DstStart AS DATETIME
,@DstEnd AS DATETIME
,@Mar1 AS DATETIME
,@Nov1 AS DATETIME
,@MarTime AS TIME
,@NovTime AS TIME
,@Mar1Day AS INT
,@Nov1Day AS INT
,@MarDiff AS INT
,@NovDiff AS INT
SELECT
@Year = YEAR(@UtcDateTime)
,@MarTime = CONVERT(TIME, DATEADD(HOUR, -@UtcOffset, '1900-01-01 02:00'))
,@NovTime = CONVERT(TIME, DATEADD(HOUR, -@UtcOffset - 1, '1900-01-01 02:00'))
,@Mar1 = CONVERT(CHAR(16), @Year + '-03-01 ' + CONVERT(CHAR(5), @MarTime), 126)
,@Nov1 = CONVERT(CHAR(16), @Year + '-11-01 ' + CONVERT(CHAR(5), @NovTime), 126)
,@Mar1Day = DATEPART(WEEKDAY, @Mar1)
,@Nov1Day = DATEPART(WEEKDAY, @Nov1)
--Get number of days between Mar 1 and DST start date
IF @Mar1Day = 1 SET @MarDiff = 7
ELSE SET @MarDiff = 15 - @Mar1Day
--Get number of days between Nov 1 and DST end date
IF @Nov1Day = 1 SET @NovDiff = 0
ELSE SET @NovDiff = 8 - @Nov1Day
--Get DST start and end dates
SELECT
@DstStart = DATEADD(DAY, @MarDiff, @Mar1)
,@DstEnd = DATEADD(DAY, @NovDiff, @Nov1)
--Change UTC offset if @UtcDateTime is in DST Range
IF @UtcDateTime >= @DstStart AND @UtcDateTime < @DstEnd SET @UtcOffset = @UtcOffset + 1
--Get Conversion
SET @PstDateTime = DATEADD(HOUR, @UtcOffset, @UtcDateTime)
RETURN @PstDateTime
END
GO
데이터가 많을 때 one off function이 너무 느리다는 것을 알게 되었습니다.그래서 시간 차이를 계산할 수 있는 표 함수에 결합함으로써 이 작업을 수행했습니다.기본적으로 시간 오프셋이 있는 날짜/시간 세그먼트입니다.1년은 4줄일 것이다.그래서 테이블 기능은
dbo.fn_getTimeZoneOffsets('3/1/2007 7:00am', '11/5/2007 9:00am', 'EPT')
는 다음 테이블을 반환합니다.
startTime endTime offset isHr2
3/1/07 7:00 3/11/07 6:59 -5 0
3/11/07 7:00 11/4/07 6:59 -4 0
11/4/07 7:00 11/4/07 7:59 -5 1
11/4/07 8:00 11/5/07 9:00 -5 0
서머타임이 설명되네요.다음은 사용 방법의 예입니다.블로그 투고 전문은 이쪽입니다.
select mt.startTime as startUTC,
dateadd(hh, tzStart.offset, mt.startTime) as startLocal,
tzStart.isHr2
from MyTable mt
inner join dbo.fn_getTimeZoneOffsets(@startViewUTC, @endViewUTC, @timeZone) tzStart
on mt.startTime between tzStart.startTime and tzStart.endTime
declare @mydate2 datetime
set @mydate2=Getdate()
select @mydate2 as mydate,
dateadd(minute, datediff(minute,getdate(),@mydate2),getutcdate())
나중에 이것은 매우 잘 작동한다.서버에 시간을 절약한 시간을 'utc'로 통지하고 특정 시간대(이 경우 '브라질/동부')로 변환하도록 요청합니다.
quiz_step_progresses.created_at at time zone 'utc' at time zone 'Brazil/East'
다음 선택 항목을 사용하여 전체 시간대 목록을 가져옵니다.
select * from pg_timezone_names;
자세한 것은 이쪽을 봐 주세요.
https://popsql.com/learn-sql/postgresql/how-to-convert-utc-to-local-time-zone-in-postgresql
론의 답변에는 오류가 포함되어 있습니다.UTC와 동등한 UTC가 필요한 현지시간으로 오전 2시를 사용합니다.Ron의 답변에 대해 코멘트를 할 수 있는 평가 포인트가 부족하기 때문에 수정 버전은 다음과 같습니다.
-- =============================================
-- Author: Ron Smith
-- Create date: 2013-10-23
-- Description: Converts UTC to DST
-- based on passed Standard offset
-- =============================================
CREATE FUNCTION [dbo].[fn_UTC_to_DST]
(
@UTC datetime,
@StandardOffset int
)
RETURNS datetime
AS
BEGIN
declare
@DST datetime,
@SSM datetime, -- Second Sunday in March
@FSN datetime -- First Sunday in November
-- get DST Range
set @SSM = datename(year,@UTC) + '0314'
set @SSM = dateadd(hour,2 - @StandardOffset,dateadd(day,datepart(dw,@SSM)*-1+1,@SSM))
set @FSN = datename(year,@UTC) + '1107'
set @FSN = dateadd(second,-1,dateadd(hour,2 - (@StandardOffset + 1),dateadd(day,datepart(dw,@FSN)*-1+1,@FSN)))
-- add an hour to @StandardOffset if @UTC is in DST range
if @UTC between @SSM and @FSN
set @StandardOffset = @StandardOffset + 1
-- convert to DST
set @DST = dateadd(hour,@StandardOffset,@UTC)
-- return converted datetime
return @DST
END
UNIX 타임스탬프는 특정 날짜와 Unix Epoch 사이의 초수일 뿐입니다.
SELECT DATIFF (SECond, {d '1970-01-01'}, GETDATE() // SQL Server에서 UNIX 타임스탬프가 반환됩니다.
Country Offset Function to Unix Time Stamp In SQL Server를 사용하여 로컬 날짜에서 Unix UTC로 변환하는 함수를 만들 수 있습니다.
간단해요.Azure SQL Server에 대해 다음을 시도해 보십시오.
SELECT YourDateTimeColumn AT TIME ZONE 'Eastern Standard Time' FROM YourTable
로컬 SQL Server의 경우:
SELECT CONVERT(datetime2, SWITCHOFFSET(CONVERT(datetimeoffset, gETDATE()), DATENAME(TzOffset, gETDATE() AT TIME ZONE 'Eastern Standard Time'))) FROM YourTable
아직 이 문제를 해결하려는 사용자를 위해 SQL Server 2017에서 사용할 수 있는 개념 증명서를 소개합니다.
declare
@StartDate date = '2020-01-01'
;with cte_utc as
(
select
1 as i
,CONVERT(datetime, @StartDate) AS UTC
,datepart(weekday, CONVERT(datetime, @StartDate)) as Weekday
,datepart(month, CONVERT(datetime, @StartDate)) as [Month]
,datepart(YEAR, CONVERT(datetime, @StartDate)) as [Year]
union all
Select
i + 1
,dateadd(d, 1, utc)
,datepart(weekday, CONVERT(datetime, dateadd(d, 1, utc))) as Weekday
,datepart(month, CONVERT(datetime, dateadd(d, 1, utc))) as [Month]
,datepart(YEAR, CONVERT(datetime, dateadd(d, 1, utc))) as [Year]
from
cte_utc
where
(i + 1) < 32767
), cte_utc_dates as
(
select
*,
DENSE_RANK()OVER(PARTITION BY [Year], [Month], [Weekday] ORDER BY Utc) WeekDayIndex
from
cte_utc
), cte_hours as (
select 0 as [Hour]
union all
select [Hour] + 1 from cte_hours where [Hour] < 23
)
select
d.*
, DATEADD(hour, h.Hour, d.UTC) AS UtcTime
,CONVERT(datetime, DATEADD(hour, h.Hour, d.UTC) AT TIME ZONE 'UTC' AT TIME ZONE 'Central Standard Time') CST
,CONVERT(datetime, DATEADD(hour, h.Hour, d.UTC) AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time') EST
from
cte_utc_dates d, cte_hours h
where
([Month] = 3 and [Weekday] = 1 and WeekDayIndex = 2 )-- dst start
or
([Month] = 11 and [Weekday] = 1 and WeekDayIndex = 1 )-- dst end
order by
utc
OPTION (MAXRECURSION 32767)
GO
경고 - 다음을 사용하는 경우(분 단위 대신 밀리초 단위)
SELECT DATEADD(ms, DATEDIFF(ms, GETUTCDATE(), GETDATE()), MyTable.UtcColumn)
AS ColumnInLocalTime
FROM MyTable
DATIFF 부품은 항상 같은 번호를 반환하지 않습니다.따라서 DateTimes를 밀리초 단위로 비교하는 데 사용하지 마십시오.
그러면 DST에서 서버 시간을 얻을 수 있습니다.
declare @dt datetime
set @dt = getutcdate() -- GMT equivalent
sysdatetime offset은 DST를 고려합니다.
select [InputTime] = @dt
, [LocalTime2] = dateadd(mi, datediff(mi, sysdatetimeoffset(),getdate()), @dt)
첫 번째 함수: 이탈리아 표준시(+1, +2)에 대해 설정된 스위치 날짜: 3월 및 10월 마지막 일요일 현재 표준시와 날짜 사이의 차이를 파라미터로 반환합니다.
Returns:
current timezone < parameter timezone ==> +1
current timezone > parameter timezone ==> -1
else 0
코드는 다음과 같습니다.
CREATE FUNCTION [dbo].[UF_ADJUST_OFFSET]
(
@dt_utc datetime2(7)
)
RETURNS INT
AS
BEGIN
declare @month int,
@year int,
@current_offset int,
@offset_since int,
@offset int,
@yearmonth varchar(8),
@changeoffsetdate datetime2(7)
declare @lastweek table(giorno datetime2(7))
select @current_offset = DATEDIFF(hh, GETUTCDATE(), GETDATE())
select @month = datepart(month, @dt_utc)
if @month < 3 or @month > 10 Begin Set @offset_since = 1 Goto JMP End
if @month > 3 and @month < 10 Begin Set @offset_since = 2 Goto JMP End
--If i'm here is march or october
select @year = datepart(yyyy, @dt_utc)
if @month = 3
Begin
Set @yearmonth = cast(@year as varchar) + '-03-'
Insert Into @lastweek Values(@yearmonth + '31 03:00:00.000000'),(@yearmonth + '30 03:00:00.000000'),(@yearmonth + '29 03:00:00.000000'),(@yearmonth + '28 03:00:00.000000'),
(@yearmonth + '27 03:00:00.000000'),(@yearmonth + '26 03:00:00.000000'),(@yearmonth + '25 03:00:00.000000')
--Last week of march
Select @changeoffsetdate = giorno From @lastweek Where datepart(weekday, giorno) = 1
if @dt_utc < @changeoffsetdate
Begin
Set @offset_since = 1
End Else Begin
Set @offset_since = 2
End
End
if @month = 10
Begin
Set @yearmonth = cast(@year as varchar) + '-10-'
Insert Into @lastweek Values(@yearmonth + '31 03:00:00.000000'),(@yearmonth + '30 03:00:00.000000'),(@yearmonth + '29 03:00:00.000000'),(@yearmonth + '28 03:00:00.000000'),
(@yearmonth + '27 03:00:00.000000'),(@yearmonth + '26 03:00:00.000000'),(@yearmonth + '25 03:00:00.000000')
--Last week of october
Select @changeoffsetdate = giorno From @lastweek Where datepart(weekday, giorno) = 1
if @dt_utc > @changeoffsetdate
Begin
Set @offset_since = 1
End Else Begin
Set @offset_since = 2
End
End
JMP:
if @current_offset < @offset_since Begin
Set @offset = 1
End Else if @current_offset > @offset_since Set @offset = -1 Else Set @offset = 0
Return @offset
END
그러면 날짜를 변환하는 함수가
CREATE FUNCTION [dbo].[UF_CONVERT]
(
@dt_utc datetime2(7)
)
RETURNS datetime
AS
BEGIN
declare @offset int
Select @offset = dbo.UF_ADJUST_OFFSET(@dt_utc)
if @dt_utc >= '9999-12-31 22:59:59.9999999'
set @dt_utc = '9999-12-31 23:59:59.9999999'
Else
set @dt_utc = (SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), @dt_utc) )
if @offset <> 0
Set @dt_utc = dateadd(hh, @offset, @dt_utc)
RETURN @dt_utc
END
-- 인도 표준시를 utc에서 가져옵니다.
CREATE FUNCTION dbo.getISTTime
(
@UTCDate datetime
)
RETURNS datetime
AS
BEGIN
RETURN dateadd(minute,330,@UTCDate)
END
GO
올바른 시간으로 변환할 뿐만 아니라 문자열을 다시 포맷해야 합니다.이 경우 나는 줄루 시간이 필요했다.
Declare @Date datetime;
Declare @DateString varchar(50);
set @Date = GETDATE();
declare @ZuluTime datetime;
Declare @DateFrom varchar (50);
Declare @DateTo varchar (50);
set @ZuluTime = DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), @Date);
set @DateString = FORMAT(@ZuluTime, 'yyyy-MM-ddThh:mm:ssZ', 'en-US' )
select @DateString;
Oracle을 위한 최적의 방법:
하드코드된 날짜/시간:
SELECT TO_CHAR(CAST((FROM_TZ(CAST(TO_DATE('2018-10-27 21:00', 'YYYY-MM-DD HH24:MI') AS TIMESTAMP), 'UTC') AT TIME ZONE 'EET') AS DATE), 'YYYY-MM-DD HH24:MI') UTC_TO_EET FROM DUAL
Result: 2018-10-28 00:00
열 및 테이블 이름 포함:
SELECT TO_CHAR(CAST((FROM_TZ(CAST(COLUMN_NAME AS TIMESTAMP), 'UTC') AT TIME ZONE 'EET') AS DATE), 'YYYY-MM-DD HH24:MI') UTC_TO_EET FROM TABLE_NAME
UTC에서 로컬로, 로컬에서 UTC로 변환하는 코드를 가지고 있습니다.
DECLARE @usersTimezone VARCHAR(32)='Europe/London'
DECLARE @utcDT DATETIME=GetUTCDate()
DECLARE @userDT DATETIME=[dbo].[funcUTCtoLocal](@utcDT, @usersTimezone)
그리고.
DECLARE @usersTimezone VARCHAR(32)='Europe/London'
DECLARE @userDT DATETIME=GetDate()
DECLARE @utcDT DATETIME=[dbo].[funcLocaltoUTC](@userDT, @usersTimezone)
함수는 NodaTime에서 제공하는IANA/TZDB 내의 타임존의 전부 또는 일부를 지원할 수 있습니다.https://nodatime.org/TimeZones 에서 전체 목록을 참조하십시오.
제 사용 사례는 '현재' 창만 있으면 된다는 것을 의미하므로, 지금부터 약 +/- 5년 후 시간 변환이 가능합니다.즉, 특정 날짜 범위 내의 시간대 간격마다 코드를 생성하는 방식이기 때문에 시간이 많이 필요한 경우에는 이 방법이 적합하지 않을 수 있습니다.
이 프로젝트는 GitHub: https://github.com/elliveny/SQLServerTimeConversion에 있습니다.
utc 시각에서 로컬 시각으로 변환하기 위해 switchoffset을 사용했습니다.시간대 오프셋은 datname(tzoffset, systemdatetimeoffset)을 사용하여 확인할 수 있습니다.마찬가지로 경과시간을 취득하려면 datediff 함수에 대해 utcdate 시간을 utc로 유지하는 것을 사용합니다.
select
,[Field1]
,Format(SWITCHOFFSET([MyDateOnUTC],DATENAME(TZOFFSET, SYSDATETIMEOFFSET())),'MM/dd/yyyy hh:mm:ss tt') UtcToLocalTime
,datediff(minute,[ClaimedOnUTC],getutcdate()) ElapsedMinutes
from dbo.my_table
여기 dst를 고려한 더 간단한 것이 있습니다.
CREATE FUNCTION [dbo].[UtcToLocal]
(
@p_utcDatetime DATETIME
)
RETURNS DATETIME
AS
BEGIN
RETURN DATEADD(MINUTE, DATEDIFF(MINUTE, GETUTCDATE(), @p_utcDatetime), GETDATE())
END
이 기능은 별도의 테이블이나 루프를 사용하는 다른 솔루션보다 빠르다는 것을 알게 되었습니다.그냥 기본적인 사건 진술서일 뿐이에요4월부터 10월까지의 모든 달의 오프셋은 -4시간(동부 표준시)이므로 프린지 요일에 몇 줄의 케이스 라인을 추가하면 됩니다.그렇지 않으면 오프셋은 -5시간입니다.
이는 UTC에서 동부시간으로의 변환에 고유하지만 필요에 따라 다른 시간대 기능을 추가할 수 있습니다.
USE [YourDatabaseName]
GO
/****** Object: UserDefinedFunction [dbo].[ConvertUTCtoEastern] Script Date: 11/2/2016 5:21:52 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[ConvertUTCtoEastern]
(
@dtStartDate DATETIME
)
RETURNS DATETIME
AS
BEGIN
DECLARE @Working DATETIME
DECLARE @Returned DATETIME
SET @Working = @dtStartDate
SET @Working =
case when month(@Working) between 4 and 10 then dateadd(HH,-4,@Working)
when @Working between '2017-03-12' and '2017-11-05' then dateadd(HH,-4,@Working)
when @Working between '2016-03-13' and '2016-11-06' then dateadd(HH,-4,@Working)
when @Working between '2015-03-08' and '2015-11-01' then dateadd(HH,-4,@Working)
when @Working between '2014-03-09' and '2014-11-02' then dateadd(HH,-4,@Working)
when @Working between '2013-03-10' and '2013-11-03' then dateadd(HH,-4,@Working)
when @Working between '2012-03-11' and '2012-11-04' then dateadd(HH,-4,@Working)
else dateadd(HH,-5,@Working) end
SET @Returned = @Working
RETURN @Returned
END
GO
언급URL : https://stackoverflow.com/questions/8038744/convert-datetime-column-from-utc-to-local-time-in-select-statement
'sourcecode' 카테고리의 다른 글
| ID 컬럼을 사용한 테이블 작성 방법 (0) | 2023.04.18 |
|---|---|
| C#에서 FindTimeZoneById()와 함께 사용하는 시간대 ID 목록? (0) | 2023.04.18 |
| bash에서 "-ne"은 무슨 뜻입니까? (0) | 2023.04.18 |
| 날짜 문자열에 대한 Oracle to_date 함수 사용(밀리초) (0) | 2023.04.18 |
| SQL Server가 대소문자를 무시하는 식입니다. (0) | 2023.04.13 |