【问题标题】:T-SQL: Convert the value of datetime field from UTC to CET timezoneT-SQL:将日期时间字段的值从 UTC 转换为 CET 时区
【发布时间】:2014-11-23 22:06:00
【问题描述】:

我有一个将日期存储为带有 UTC 偏移量的日期时间的数据库。 如何在 select 语句中将这些日期从 UTC 转换为 CET?

是否有某种语法糖可以处理整个日光秋/冬和春/夏偏移的事情?

编辑: 我发现 CodePlex 上的 this 库很有用:

DateTimeUtil

一组用于扩展日期时间处理的 UDF 和配置数据,例如。 G。它提供了简单的时区转换,包括。使用本机 T-SQL(无 CLR)支持夏令时。

【问题讨论】:

  • 试试这个 - SELECT DATEADD(SECOND, DATEDIFF(SECOND, GETUTCDATE(), GETDATE()), ColumnWithUTCDate) as CETCol from YourTable;
  • 只是出于好奇,您使用的是 .NET 吗?如果是,那么您在那里处理偏移量/时区会容易得多
  • #Kirshnraj Rana +1,这很聪明。不幸的是,有时我需要不同时区的时间。 #ShekharPankaj - 不,只是来自 ssms 的查询。
  • 看这个链接:mssqltips.com/sqlservertip/3173/… 它列出了所有的步骤。
  • DATETIME 不包含时区信息。 CET 总是比 UTC 早一小时。如果您只是为了显示目的而这样做,只需在该字段中添加 1 小时即可。

标签: sql sql-server datetime


【解决方案1】:
SELECT CONVERT(VARCHAR, dbo.udfToLocalTime(t.CreatedDateTime, '1'), 113)
FROM yourtable t 

如需更新:

UPDATE yourtable t 
SET t.CreatedDateTime = CONVERT(VARCHAR, dbo.udfToLocalTime(t.CreatedDateTime, '1'), 113)

使用如下的 UDF

CREATE FUNCTION udfToLocalTime
(
   @UtcDateTimeAS DATETIME
   ,@UtcOffset AS INT = -8 --PST
)
RETURNS DATETIME
AS 
BEGIN

    DECLARE @PstDateTimeAS DATETIME
            ,@Year  AS CHAR(4)
            ,@DstStart  AS DATETIME
            ,@DstEndAS 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

【讨论】:

  • 可能是我遗漏了什么,但是您如何计算夏季和冬季时间的一小时。
  • @VelislavMarinov 。已修改解决方案以处理夏令时。测试 SELECT convert(VARCHAR, dbo.udfToLocalTime('2014-02-15 00:00:00.000','1'), 113) SELECT convert(VARCHAR, dbo.udfToLocalTime('2014-04-15 00:00: 00.000', '1'), 113) 选择转换(VARCHAR, dbo.udfToLocalTime('2014-09-15 00:00:00.000','1'), 113) 选择转换(VARCHAR, dbo.udfToLocalTime('2014 -11-15 00:00:00.000', '1'), 113)
  • Assumption-Offset参数作为冬季的偏移量
【解决方案2】:

如果您的数据库包含 UTC 日期,那就太完美了。更好的方法是使用您的操作系统时区偏移量。

例如:

select
  dateadd(minute,DATEPART(TZ, SYSDATETIMEOFFSET()), YourUTCDate) as timestamp
from YourTable

【讨论】:

    【解决方案3】:

    使用下面的函数来转换 Date TImeZones。

    create or replace FUNCTION timezoneConverter 
    (v_date in date, inputDateZone in varchar2 default 'UTC', outputDateZone in varchar2 default 'UTC')
    return date AS date_out date;
    BEGIN
        SELECT
            to_date(
                to_char(FROM_TZ(to_timestamp(to_char( v_date,'dd.mm.yyyy hh24:mi:ss' ),'dd.mm.yyyy hh24:mi:ss'),
            to_char(inputDateZone)) AT TIME ZONE
            to_char(outputDateZone),
            'dd.mm.yyyy hh24:mi:ss'), 'dd.mm.yyyy hh24:mi:ss')
        into date_out FROM dual;
        return date_out;
    EXCEPTION
        when others then
            DBMS_OUTPUT.put_line('Date:' || v_date || 'TZ:' || inputDateZone || '-' || outputDateZone || ' / ' || sqlcode || ' / ' || SQLERRM(sqlcode));
            --date_out := to_date(to_char(v_date-1/24, 'yyyymmddhh24miss'), 'yyyymmddhh24miss');
            date_out := null;
            return date_out;
    END;
    /
    

    日光 中欧时间 (CET) 与中欧夏令时间 (CEST)

    Short Hour 跳过第二个小时。 Note: hours shift because clocks change forward 1 hour.

    --set serveroutput on; -- View -> Dbms Output : set serveroutput on [serveroutput must be set ON or OFF or OPTIMIZED or UNOPTIMIZED]
    SELECT
     timezoneConverter(to_timestamp('2020-03-29T01:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'CET', 'UTC') CETtoUTC1, -- 29-MAR-2020 00:00:00
     timezoneConverter(to_timestamp('2020-03-29T02:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'CET', 'UTC') CETtoUTC2, -- (null)
     timezoneConverter(to_timestamp('2020-03-29T02:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'UTC', 'CET') UTCtoCET FROM dual; -- 29-MAR-2020 04:00:00
    
    -- Date:29-MAR-2020 02:00:00TZ:CET-UTC / -1878 / ORA-01878: specified field not found in datetime or interval
    

    Long Hour 第 2 小时重复 Note: hours shift because clocks change backward 1 hour.

    SELECT
     timezoneConverter(to_timestamp('2020-10-25T02:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'UTC', 'CET') UTCtoCET, -- 25-OCT-2020 03:00:00
     timezoneConverter(to_timestamp('2020-10-25T02:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'CET', 'UTC') CETtoUTC2, -- 25-OCT-2020 01:00:00
     timezoneConverter(to_timestamp('2020-10-25T01:00Z', 'yyyy-mm-dd"T"hh24:mi"Z"'), 'CET', 'UTC') CETtoUTC1 FROM dual; -- 24-OCT-2020 23:00:00
    

    以下示例将一个时区的日期时间值转换为另一个时区:docs.oracle.com

    SELECT FROM_TZ(CAST(TO_DATE('1999-12-01 11:00:00', 
          'YYYY-MM-DD HH:MI:SS') AS TIMESTAMP), 'America/New_York') 
       AT TIME ZONE 'America/Los_Angeles' "West Coast Time" 
       FROM DUAL;
    
    West Coast Time
    ------------------------------------------------
    01-DEC-99 08.00.00.000000 AM AMERICA/LOS_ANGELES
    

    【讨论】:

      猜你喜欢
      • 2023-04-02
      • 2020-08-18
      • 1970-01-01
      • 2017-02-04
      • 2022-11-13
      • 1970-01-01
      • 2019-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多