Tôi đã chờ đợi 5 năm cho một giải pháp thanh lịch hơn nhưng kể từ khi một đã không nổi lên, tôi sẽ đăng những gì tôi đã sử dụng cho đến nay ...
CREATE FUNCTION [dbo].[UDTToLocalTime](@UDT AS DATETIME)
RETURNS DATETIME
AS
BEGIN
--====================================================
--Set the Timezone Offset (NOT During DST [Daylight Saving Time])
--====================================================
DECLARE @Offset AS SMALLINT
SET @Offset = -5
--====================================================
--Figure out the Offset Datetime
--====================================================
DECLARE @LocalDate AS DATETIME
SET @LocalDate = DATEADD(hh, @Offset, @UDT)
--====================================================
--Figure out the DST Offset for the UDT Datetime
--====================================================
DECLARE @DaylightSavingOffset AS SMALLINT
DECLARE @Year as SMALLINT
DECLARE @DSTStartDate AS DATETIME
DECLARE @DSTEndDate AS DATETIME
--Get Year
SET @Year = YEAR(@LocalDate)
--Get First Possible DST StartDay
IF (@Year > 2006) SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-03-08 02:00:00'
ELSE SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-04-01 02:00:00'
--Get DST StartDate
WHILE (DATENAME(dw, @DSTStartDate) <> 'sunday') SET @DSTStartDate = DATEADD(day, 1,@DSTStartDate)
--Get First Possible DST EndDate
IF (@Year > 2006) SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-11-01 02:00:00'
ELSE SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-10-25 02:00:00'
--Get DST EndDate
WHILE (DATENAME(dw, @DSTEndDate) <> 'sunday') SET @DSTEndDate = DATEADD(day,1,@DSTEndDate)
--Get DaylightSavingOffset
SET @DaylightSavingOffset = CASE WHEN @LocalDate BETWEEN @DSTStartDate AND @DSTEndDate THEN 1 ELSE 0 END
--====================================================
--Finally add the DST Offset
--====================================================
RETURN DATEADD(hh, @DaylightSavingOffset, @LocalDate)
END
GO
Ghi chú:
này là dành cho máy chủ Bắc Mỹ mà quan sát Daylight Saving Time. Vui lòng thay đổi @Offest biến để các múi giờ bù đắp của máy chủ chạy các chức năng SQL (Trong khi KHÔNG Quan sát thời gian Daylight Savings) ...
--====================================================
--Set the Timezone Offset (NOT During DST [Daylight Saving Time])
--====================================================
DECLARE @Offset AS SMALLINT
SET @Offset = -5
Như các quy tắc DST thay đổi cập nhật chúng ở đây ...
--Get First Possible DST StartDay
IF (@Year > 2006) SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-03-08 02:00:00'
ELSE SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-04-01 02:00:00'
--Get DST StartDate
WHILE (DATENAME(dw, @DSTStartDate) <> 'sunday') SET @DSTStartDate = DATEADD(day, 1,@DSTStartDate)
--Get First Possible DST EndDate
IF (@Year > 2006) SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-11-01 02:00:00'
ELSE SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-10-25 02:00:00'
--Get DST EndDate
WHILE (DATENAME(dw, @DSTEndDate) <> 'sunday') SET @DSTEndDate = DATEADD(day,1,@DSTEndDate)
Chúc mừng,
cảm ơn, hãy thử điều đó, tôi sẽ cho bạn biết – Michel
tìm ra cách chuyển đổi utc thành các múi giờ khác, AND đã cố gắng triển khai hàm SqlCLR. Tuy nhiên, việc kết hợp chúng không hoạt động, bởi vì tôi đang sử dụng đối tượng TimeZoneInfo để tính toán các khoảng thời gian khác nhau, và tôi không thể tham chiếu đến assembly mà nó nằm trong SqlProject của tôi (vì có vẻ như bạn chỉ có thể tham khảo một tập hợp con của .net khuôn khổ) – Michel
OK - tò mò là tại sao bạn cần lớp TimeZoneInfo cho yêu cầu của bạn chuyển đổi UTC thành Local. Nếu máy chủ SQL của bạn được cấu hình là trong _your_ múi giờ địa phương (đã đồng ý - đây là một ràng buộc), thì hàm C# của bạn trở thành một cái gì đó như 'trả về SqlDateTime mới (utcDate.Value.toLocalTime());' . Bạn không cần chỉ định múi giờ. Tôi có hiểu sai không? –