2009-07-30 7 views
1

Nous essayons d'interpréter les données stockées dans la table TIMEZONESRULESDATA d'Axapata. En particulier, nous aimerions savoir comment il stocke les heures de début et de fin de l'heure d'été. Jusqu'à présent, je suppose:Axapta/DynamicsAx: Conversion datetime UTC

TZENUM: référencement clé étrangère TIMEZONESLIST (nom de fuseau horaire et identifiant)
ANNÉE: 0 si la règle est valable indéfiniment ou une année où la règle de fuseau horaire est en vigueur
BIAS: décalage heure UTC en quelques minutes
DBIAS: décalage de l'heure d'été (ajouté à BIAS pour obtenir au total décalé par rapport à UTC)

maintenant, pour la partie que je ne comprends pas:

dAnnée, DMONTH, DDAYOFWEEK, DDAY, Dhour, DMINUTE, DSECOND
SYEAR, SMONTH, SDA YOFWEEK, SDAY, SHOUR, SMINUTE, SSECOND

Je suppose à partir des dates que le D * est la date de début de DST et S * est la fin. Cependant, je ne comprends pas pourquoi il faudrait un an et un jour de la semaine. En outre, * DAY ne semble pas indiquer le jour du mois - au moins, il n'indique pas le bon pour changer DST. Il ne semble pas non plus correspondre aux dates auxquelles l'autoconversion DateTimeUtil ou Form d'Axapta convertit les dates.

Est-ce que quelqu'un sait comment interpréter cette table? Ou où pourrais-je le chercher?

Sören

Répondre

0

DDAY et SDAY représente semaine du mois (1-4, 5 = semaine dernière)

DDAYOFWEEK et SDAYOFWEEK représente le jour de la semaine (0 = dimanche)

Comment utiliserez-vous cette information?

+0

Il nous manquait la partie 5 = dernière semaine - merci! Ai-je raison de supposer que si une entrée n'est valable que pour une année spécifique, le SDAY sera le jour exact du mois? Aussi, qu'est-ce que cela signifie d'avoir une entrée non-0 pour l'année? Les paramètres sont-ils valables uniquement pour cette année ou à partir de cette année? Nous avons l'intention d'utiliser les données pour écrire notre propre SQL local time-time/DST en conversion UTC (nous ne pouvons pas utiliser X ++ dans ce cas). L'idée consiste à utiliser le datatype datetimeoffset de SQL Server pour stocker les dates-heures. – BuschnicK

+0

Je ne connais pas le sens exact de l'année. AX est préparé pour l'importation des règles de fuseau horaire, donc mon estimation serait l'année spécifique seulement. Les tests montreront. Bonne chance avec votre conversion en heure locale, mais mon sentiment initial est que vous êtes sur une mauvaise piste. –

+0

"mauvaise piste" - mon instinct est d'accord avec vous. Cependant, que proposez-vous? Nous ne pouvons utiliser que SQL et nous devons convertir des dates arbitraires (passées, présentes, futures) d'un fuseau horaire arbitraire en UTC. – BuschnicK

1

DDAY et sdayregardé comme ils indiquent la semaine du mois, mais nous avons trouvé DDAY - et sday -values ​​de 6, 23 ou 28. Sont-ce les semaines du année, ou les valeurs> 5 ont-elles été détournées pour des jours individuels?

Ma théorie était la suivante: avec DMONTH = 8 et DDAYOFWEEK = 6, nous avons

  • DDAY = 4 ==> 4ème samedi en Août
  • DDAY = 5 ==> dernier samedi d'août
  • DDAY = n> 5 ==> n-août (conflit possible avec DDAYOFWEEK?)

Alors, quelles sont sday s et DDAY s qui sont plus de 5?

0

J'ai créé deux fonctions SQL pour convertir les dates Dynamics AX UTC en date/heure de fuseau horaire approprié à partir de la table TIMEZONESRULESDATA. Ils semblent travailler dans les scénarios que j'ai testés, mais je serais ravi de recevoir des commentaires.

La première fonction est amenée DateTime UTC et TZID de toute table de AX et génère la date/heure dans le fuseau horaire avec un réglage de l'heure d'été:

-- *** 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 @[email protected] 

-- 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 [email protected] 

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 @[email protected] 
         SET @[email protected] 
        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 

La deuxième fonction est les économies diurnes commencent ou date de fin basée sur les paramètres alimentés par les champs TIMEZONESRULESDATA:

-- *** 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 @[email protected] + 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 
Questions connexes