Datetime Axapta/DynamicsAx:UTC日期时间转换

Datetime Axapta/DynamicsAx:UTC日期时间转换,datetime,utc,axapta,microsoft-dynamics,ax,Datetime,Utc,Axapta,Microsoft Dynamics,Ax,我们正在尝试解释Axapata的TimeZoneRulesData表中存储的数据。特别是,我们想弄清楚它是如何存储DST开始/结束时间的。到目前为止,我的猜测是: TZENUM:外键引用时区列表(时区名称和标识符) 年份:如果规则无限期有效或时区规则生效的年份,则为0 偏差:以分钟为单位的UTC时间偏移量 DBIAS:DST的偏移量(添加到偏差中以获得UTC的总偏移量) 至于我不明白的部分: 戴亚尔、第六个月、第五周、第五天、第四小时、第五天、第二天 SYEAR,SMONTH,SDAYOFWEE

我们正在尝试解释Axapata的TimeZoneRulesData表中存储的数据。特别是,我们想弄清楚它是如何存储DST开始/结束时间的。到目前为止,我的猜测是:

TZENUM:外键引用时区列表(时区名称和标识符)
年份:如果规则无限期有效或时区规则生效的年份,则为0
偏差:以分钟为单位的UTC时间偏移量
DBIAS:DST的偏移量(添加到偏差中以获得UTC的总偏移量)

至于我不明白的部分:

戴亚尔、第六个月、第五周、第五天、第四小时、第五天、第二天
SYEAR,SMONTH,SDAYOFWEEK,SDAY,SHOUR,SMINUTE,SSECOND

我会根据日期猜测,D*是DST的开始日期,S*是结束日期。然而,我不明白为什么它需要一年零一天的工作时间。此外,*天似乎并不表示月份的哪一天-至少它不表示切换DST的正确日期。它似乎也与Axapta自己的DateTimeUtil或表单自动转换转换日期的日期不一致

有人知道怎么翻译这张桌子吗?或者我在哪里可以找到它


Sören

DDAY
SDAY
表示每月的一周(1-4,5=上周)

DDAYOFWEEK
SDAYOFWEEK
表示一周中的某一天(0=周日)


您将如何使用此信息?

DDAY
SDAY
表示每月的一周(1-4,5=上周)

DDAYOFWEEK
SDAYOFWEEK
表示一周中的某一天(0=周日)


您将如何使用此信息?

SDAY看起来像是表示月份的一周,但后来我们发现DDAYSDAY的值为6、23或28。这些是一年中的几周,还是单个天数的值大于5

我的理论是:d月=8和d周=6,我们有

  • DDAY=4==>8月的第四个星期六
  • 去年8月的上周六
  • DDAY=n>5==>8月n日(可能与DDAYOFWEEK发生冲突?)

因此,大于5的SDAYs和DDAYs是什么?

DDAYSDAY看起来像是表示月份的一周,但我们发现DDAY-和SDAY的值为6、23或28。这些是一年中的几周,还是单个天数的值大于5

我的理论是:d月=8和d周=6,我们有

  • DDAY=4==>8月的第四个星期六
  • 去年8月的上周六
  • DDAY=n>5==>8月n日(可能与DDAYOFWEEK发生冲突?)

那么什么是大于5的SDAYs和DDAYs?

我编写了两个SQL函数,用于将Dynamics AX UTC日期从时区规则数据表转换为适当的时区日期/时间。它们似乎在我测试过的场景中工作,但我很乐意得到反馈

第一个函数从任何AX表中输入UTC日期时间和TZID,并生成时区中的日期/时间,以及任何夏令时调整:

-- *** IMPORTANT NOTE: @@DATEFIRST must be 7 for this to work ***
CREATE FUNCTION [dbo].[ConvertUTCDateTime] (@DateTime DATETIME, @TZID INT)
RETURNS DATETIME
AS
BEGIN

DECLARE @AdjustedDateTime DATETIME
SET @AdjustedDateTime=@DateTime

-- Fields to be extracted from TIMEZONESRULESDATA record for TZID
DECLARE @Bias INT, @DBias INT
DECLARE @DMonth INT, @DDayOfWeek INT, @DDay INT, @DHour INT, @DMinute INT, @DSecond INT     -- Start of Daylight Saving
DECLARE @SMonth INT, @SDayOfWeek INT, @SDay INT, @SHour INT, @SMinute INT, @SSecond INT     -- End of Daylight Saving
-- Daylight Saving Date/Time ranges
DECLARE @DSTFromDateTime1 DATETIME, @DSTToDateTime1 DATETIME, @DSTFromDateTime2 DATETIME, @DSTToDateTime2 DATETIME

SELECT
    @Bias=tzr.BIAS,@DBias=tzr.DBIAS,
    @DMonth=tzr.DMONTH, @DDayOfWeek=tzr.DDAYOFWEEK, @DDay=tzr.DDAY, @DHour=tzr.DHOUR, @DMinute=tzr.DMINUTE, @DSecond=tzr.DSECOND,
    @SMonth=tzr.SMONTH, @SDayOfWeek=tzr.SDAYOFWEEK, @SDay=tzr.SDAY, @SHour=tzr.SHOUR, @SMinute=tzr.SMINUTE, @SSecond=tzr.SSECOND
FROM MyAXDatabase..TIMEZONESRULESDATA tzr
WHERE tzr.RULEID=@TZID

IF @Bias IS NOT NULL
    BEGIN
        SET @AdjustedDateTime=DATEADD(MINUTE, (-1)*@Bias, @DateTime )       -- Standard Time Zone Adjustment from UTC
        IF @DMonth>0    -- If there is Daylight Saving
            BEGIN
                SET @DSTFromDateTime1=dbo.GetDSTDateTime(@AdjustedDateTime, @DMonth, @DDayOfWeek, @DDay, @DHour, @DMinute, @DSecond )   -- Get DS Start date in year
                SET @DSTToDateTime2=dbo.GetDSTDateTime(@AdjustedDateTime, @SMonth, @SDayOfWeek, @SDay, @SHour, @SMinute, @SSecond ) -- Get DS End date in year
                IF @DSTFromDateTime1>@DSTToDateTime2
                    BEGIN
                        SET @DSTToDateTime1= DATEADD(SECOND, -1, CAST(DATEFROMPARTS( YEAR(@AdjustedDateTime)+1, 1, 1) as DATETIME)) -- End of Current Year
                        SET @DSTFromDateTime2= DATEFROMPARTS( YEAR(@AdjustedDateTime), 1, 1)                        -- Start of Current Year
                    END
                ELSE
                    BEGIN
                        SET @DSTToDateTime1=@DSTToDateTime2
                        SET @DSTFromDateTime2=@DSTFromDateTime1
                    END
                IF @AdjustedDateTime BETWEEN @DSTFromDateTime1 AND @DSTToDateTime1 
                    OR @AdjustedDateTime BETWEEN @DSTFromDateTime2 AND @DSTToDateTime2
                    SET @AdjustedDateTime=DATEADD(MINUTE, (-1)*@DBias, @AdjustedDateTime )  -- Make Daylight Saving adjustment if in DST date range
            END
    END

RETURN @AdjustedDateTime

END
第二个函数根据时区规则数据字段提供的参数计算夏令时开始或结束日期:

-- *** IMPORTANT NOTE: @@DATEFIRST must be 7 for this to work ***
CREATE FUNCTION [dbo].[GetDSTDateTime](
@DateTime DATETIME,     -- Base Date
@Month INT,         -- Month for Start/End of DST
@DayOfWeek INT,         -- Day of Week  0=Sun..6=Sat (based on coding in TIMEZONESRULESDATA table)
@Day INT,           -- Week of the Month (confusing?!) 1-5 ; 5 means last week
@Hour INT, 
@Minute INT, 
@Second INT
) RETURNS DATETIME
AS
BEGIN

DECLARE @MyDateTime DATETIME

SET @MyDateTime=DATEFROMPARTS( YEAR(@DateTime), @Month, 1) -- First day of DST Start/End Month from @BaseDate year
SET @DayOfWeek=@DayOfWeek + 1   -- Adjust to tie in with SQL DoW 1-7

-- Establish first selected DayOfWeek in the month
IF @DayOfWeek >= DATEPART(WEEKDAY, @MyDateTime )
    SET @MyDateTime=DATEADD(DAY, @DayOfWeek - DATEPART(WEEKDAY, @MyDateTime), @MyDateTime)
ELSE
    SET @MyDateTime=DATEADD(DAY, 7-(DATEPART(WEEKDAY, @MyDateTime) - @DayOfWeek), @MyDateTime)

-- Add the appropriate number of weeks
SET @MyDateTime=DATEADD(DAY, 7*(@Day-1), @MyDateTime)

-- For last week of month ensure that date is in correct month
WHILE MONTH(@MyDateTime)<>@Month
    BEGIN
        SET @MyDateTime=DATEADD(DAY, -7, @MyDateTime)
    END;

-- Add on Hours, Minutes and Seconds
SET @MyDateTime=DATEADD(SECOND, @Second, DATEADD(MINUTE, @Minute, DATEADD(HOUR, @Hour, @MyDateTime)))

RETURN @MyDateTime

END
-***重要注意事项:@@DATEFIRST必须为7才能工作***
创建函数[dbo]。[GetDSTDateTime](
@日期时间日期时间,--基准日期
@月整数,DST开始/结束的月份
@DayOfWeek INT,--一周中的第0天=星期日..6=星期六(基于时区规则数据表中的编码)
@Day INT,--本月的一周(混乱?!)1-5;5表示上周
@整小时,
@分钟整数,
@第二整数
)返回日期时间
作为
开始
声明@MyDateTime日期时间
设置@MyDateTime=DATEFROMPARTS(年(@DateTime),@Month,1)--DST开始/结束月的第一天从@BaseDate年开始
设置@DayOfWeek=@DayOfWeek+1——调整以与SQL DoW 1-7相匹配
--建立当月第一个选定的星期几
如果@DayOfWeek>=DATEPART(工作日,@MyDateTime)
设置@MyDateTime=DATEADD(天,@DayOfWeek-DATEPART(工作日,@MyDateTime),@MyDateTime)
其他的
设置@MyDateTime=DATEADD(第7天-(DATEPART(工作日,@MyDateTime)-@DayOfWeek),@MyDateTime)
--添加适当的周数
设置@MyDateTime=DATEADD(第7天*(@DAY-1),@MyDateTime)
--对于月的最后一周,确保日期在正确的月份
而月份(@MyDateTime)@MONTH
开始
设置@MyDateTime=DATEADD(第-7天,@MyDateTime)
结束;
--加上小时、分钟和秒
设置@MyDateTime=DATEADD(秒、@SECOND、DATEADD(分钟、@MINUTE、DATEADD(小时、@HOUR、@MyDateTime)))
返回@MyDateTime
结束

我编写了两个SQL函数,用于将Dynamics AX UTC日期从时区规则数据表转换为适当的时区日期/时间。它们似乎在我测试过的场景中工作,但我很乐意得到反馈

第一个函数从任何AX表中输入UTC日期时间和TZID,并生成时区中的日期/时间,以及任何夏令时调整:

-- *** IMPORTANT NOTE: @@DATEFIRST must be 7 for this to work ***
CREATE FUNCTION [dbo].[ConvertUTCDateTime] (@DateTime DATETIME, @TZID INT)
RETURNS DATETIME
AS
BEGIN

DECLARE @AdjustedDateTime DATETIME
SET @AdjustedDateTime=@DateTime

-- Fields to be extracted from TIMEZONESRULESDATA record for TZID
DECLARE @Bias INT, @DBias INT
DECLARE @DMonth INT, @DDayOfWeek INT, @DDay INT, @DHour INT, @DMinute INT, @DSecond INT     -- Start of Daylight Saving
DECLARE @SMonth INT, @SDayOfWeek INT, @SDay INT, @SHour INT, @SMinute INT, @SSecond INT     -- End of Daylight Saving
-- Daylight Saving Date/Time ranges
DECLARE @DSTFromDateTime1 DATETIME, @DSTToDateTime1 DATETIME, @DSTFromDateTime2 DATETIME, @DSTToDateTime2 DATETIME

SELECT
    @Bias=tzr.BIAS,@DBias=tzr.DBIAS,
    @DMonth=tzr.DMONTH, @DDayOfWeek=tzr.DDAYOFWEEK, @DDay=tzr.DDAY, @DHour=tzr.DHOUR, @DMinute=tzr.DMINUTE, @DSecond=tzr.DSECOND,
    @SMonth=tzr.SMONTH, @SDayOfWeek=tzr.SDAYOFWEEK, @SDay=tzr.SDAY, @SHour=tzr.SHOUR, @SMinute=tzr.SMINUTE, @SSecond=tzr.SSECOND
FROM MyAXDatabase..TIMEZONESRULESDATA tzr
WHERE tzr.RULEID=@TZID

IF @Bias IS NOT NULL
    BEGIN
        SET @AdjustedDateTime=DATEADD(MINUTE, (-1)*@Bias, @DateTime )       -- Standard Time Zone Adjustment from UTC
        IF @DMonth>0    -- If there is Daylight Saving
            BEGIN
                SET @DSTFromDateTime1=dbo.GetDSTDateTime(@AdjustedDateTime, @DMonth, @DDayOfWeek, @DDay, @DHour, @DMinute, @DSecond )   -- Get DS Start date in year
                SET @DSTToDateTime2=dbo.GetDSTDateTime(@AdjustedDateTime, @SMonth, @SDayOfWeek, @SDay, @SHour, @SMinute, @SSecond ) -- Get DS End date in year
                IF @DSTFromDateTime1>@DSTToDateTime2
                    BEGIN
                        SET @DSTToDateTime1= DATEADD(SECOND, -1, CAST(DATEFROMPARTS( YEAR(@AdjustedDateTime)+1, 1, 1) as DATETIME)) -- End of Current Year
                        SET @DSTFromDateTime2= DATEFROMPARTS( YEAR(@AdjustedDateTime), 1, 1)                        -- Start of Current Year
                    END
                ELSE
                    BEGIN
                        SET @DSTToDateTime1=@DSTToDateTime2
                        SET @DSTFromDateTime2=@DSTFromDateTime1
                    END
                IF @AdjustedDateTime BETWEEN @DSTFromDateTime1 AND @DSTToDateTime1 
                    OR @AdjustedDateTime BETWEEN @DSTFromDateTime2 AND @DSTToDateTime2
                    SET @AdjustedDateTime=DATEADD(MINUTE, (-1)*@DBias, @AdjustedDateTime )  -- Make Daylight Saving adjustment if in DST date range
            END
    END

RETURN @AdjustedDateTime

END
第二个函数根据时区规则数据字段提供的参数计算夏令时开始或结束日期:

-- *** IMPORTANT NOTE: @@DATEFIRST must be 7 for this to work ***
CREATE FUNCTION [dbo].[GetDSTDateTime](
@DateTime DATETIME,     -- Base Date
@Month INT,         -- Month for Start/End of DST
@DayOfWeek INT,         -- Day of Week  0=Sun..6=Sat (based on coding in TIMEZONESRULESDATA table)
@Day INT,           -- Week of the Month (confusing?!) 1-5 ; 5 means last week
@Hour INT, 
@Minute INT, 
@Second INT
) RETURNS DATETIME
AS
BEGIN

DECLARE @MyDateTime DATETIME

SET @MyDateTime=DATEFROMPARTS( YEAR(@DateTime), @Month, 1) -- First day of DST Start/End Month from @BaseDate year
SET @DayOfWeek=@DayOfWeek + 1   -- Adjust to tie in with SQL DoW 1-7

-- Establish first selected DayOfWeek in the month
IF @DayOfWeek >= DATEPART(WEEKDAY, @MyDateTime )
    SET @MyDateTime=DATEADD(DAY, @DayOfWeek - DATEPART(WEEKDAY, @MyDateTime), @MyDateTime)
ELSE
    SET @MyDateTime=DATEADD(DAY, 7-(DATEPART(WEEKDAY, @MyDateTime) - @DayOfWeek), @MyDateTime)

-- Add the appropriate number of weeks
SET @MyDateTime=DATEADD(DAY, 7*(@Day-1), @MyDateTime)

-- For last week of month ensure that date is in correct month
WHILE MONTH(@MyDateTime)<>@Month
    BEGIN
        SET @MyDateTime=DATEADD(DAY, -7, @MyDateTime)
    END;

-- Add on Hours, Minutes and Seconds
SET @MyDateTime=DATEADD(SECOND, @Second, DATEADD(MINUTE, @Minute, DATEADD(HOUR, @Hour, @MyDateTime)))

RETURN @MyDateTime

END
-***重要注意事项:@@DATEFIRST必须为7才能工作***
创建函数[dbo]。[GetDSTDateTime](
@日期时间日期时间,--基准日期
@月整数,DST开始/结束的月份
@DayOfWeek INT,--一周中的第0天=星期日..6=星期六(基于时区规则数据表中的编码)
@Day INT,--本月的一周(混乱?!)1-5;5表示上周
@整小时,
@分钟整数,
@第二整数
)返回日期时间
作为
开始
声明@MyDateTime日期时间
设置@MyDateTime=DATEFROMPARTS(年(@DateTime),@Month,1)-