Dynamics AX 2012 R2 Using DateTime In AIF Service Contract

Created at 2015-06-27 Updated at 2018-05-01 Category Microsoft Dynamics AX Tag Microsoft Dynamics AX

Unnamed QQ Screenshot20150627103313[4]

    Reinhard在AIF中使用DateTime作为服务契约的参数,与DotNet程序进行交互时,总是因为时区的问题,导致DotNet提交的System.DateTime与AIF中接收的DateTime 不一致。

    这个问题着实困扰了Reinhard 许久。为了解决这个问题,Reinhard这次专门写一篇博文,通过一系列的实验,找到通过AIF服务契约,对DateTime进行存储、获取、比较的最佳方式。

1、DateTime存储实验

    在AX中,Reinhard写了三个存储DateTime方法,分别测试了System.DateTime和UtcDateTime作为服务契约参数的不同情况。这三个服务契约如下:









[SysEntryPointAttribute]

public void saveSystemDateTime(System.DateTime _dt)

{

    ReinhardTest_Table table;

    ttsBegin;

    table.UtcDateTime=_dt;

    table.insert();

    ttsCommit;

}

[SysEntryPointAttribute]

public void saveSystemDateTime2(System.DateTime _dt)

{

    ReinhardTest_Table table;

    ttsBegin;

    table.UtcDateTime=Global::clrSystemDateTime2UtcDateTime( _dt);

    table.insert();

    ttsCommit;

}

[SysEntryPointAttribute]

public void saveUtcDateTime( utcDateTime _utcDateTime)

{

    ReinhardTest_Table table;

    ttsBegin;

    table.UtcDateTime=_utcDateTime;

    table.insert();

    ttsCommit;

}

    接着,在VS中,Reinhard调用这三个服务契约,分别存储三个不同的System.DateTime实例,看哪个服务契约能够正确地存储DateTime。这三个日期分别是:









DateTime saveSystemDateTimeDT = new DateTime(2013, 3, 3, 3, 3, 3);

DateTime saveSystemDateTime2DT = new DateTime(2014, 4, 4, 4, 4, 4);

DateTime saveUtcDateTimeDT = new DateTime(2015, 5, 5, 5, 5, 5);

    调用完毕后,到AX中,查看ReinhardTest_Table中保存的日期。

Image[4]

    Reinhard发现,只有SaveUtcDateTime这个服务契约,正确保存了DotNet中System.DateTime的值。

结论:正确的日期存储方式是SaveUtcDateTime。

2、DateTime对比实验

    在AX中,Reinhard写了两个比较DateTime方法,分别测试了System.DateTime和UtcDateTime作为服务契约参数的不同情况。这两个服务契约如下:









[SysEntryPointAttribute]

public boolean compareUtcDateTime(utcDateTime _utcDateTime)

{

    ReinhardTest_Table table;

    select table order by table.UtcDateTime desc;

    return table.UtcDateTime==_utcDateTime;

}

[SysEntryPointAttribute]

public boolean compareSystemDateTime(System.DateTime _dt)

{

    ReinhardTest_Table table;

    utcDateTime dt= Global::clrSystemDateTime2UtcDateTime(_dt);

    select table order by table.UtcDateTime desc;

    return table.UtcDateTime==dt;

}

    这里,Reinhard选择了ReinhardTest_Table表中的最后一条记录,进行比较,也就是2015-05-05 05:05:05那条。

    接着,在VS中,Reinhard调用这两个服务契约,与同一个System.DateTime实例做比较,这个DateTime是:

DateTime saveUtcDateTimeDT = new DateTime(2015, 5, 5, 5, 5, 5);

    这个DateTime其实就是Reinhard在第一个实验中,最后一个保存的那个DateTime。不出意外的话,它应该与ReinhardTest_Table表中的最后一条记录是等价的。那么,我们来看看调用的结果吧。

Image [1]

    Reinhard发现,只有CompareUtcDateTime这个服务契约,正确比较了DotNet中System.DateTime与AX中UtcDateTime的值。

    结论:正确的日期比较方式是CompareUtcDateTime。

3、DateTime获取实验

    在AX中,Reinhard写了七个获取DateTime方法,分别测试了System.DateTime和UtcDateTime作为服务契约返回值的不同情况。这七个服务契约如下:









[SysEntryPointAttribute]

public utcDateTime getUtcDateTime()

{

    ReinhardTest_Table table;

    select table order by table.UtcDateTime desc;

    return table.UtcDateTime;

}

[SysEntryPointAttribute]

public utcDateTime getUtcDateTime2()

{

    ReinhardTest_Table table;

    select table order by table.UtcDateTime desc;

    return DateTimeUtil::applyTimeZoneOffset(table.UtcDateTime ,DateTimeUtil::getUserPreferredTimeZone());

}

[SysEntryPointAttribute]

public utcDateTime getUtcDateTime3()

{

    ReinhardTest_Table table;

    str strDT;

    select table order by table.UtcDateTime desc;

    return DateTimeUtil::applyTimeZoneOffset(table.UtcDateTime ,DateTimeUtil::getCompanyTimeZone());

}

[SysEntryPointAttribute]

public System.DateTime getSystemDateTime()

{

    ReinhardTest_Table table;

    select table order by table.UtcDateTime desc;

    return table.UtcDateTime;

}

[SysEntryPointAttribute]

public System.DateTime getSystemDateTime2()

{

    ReinhardTest_Table table;

    select table order by table.UtcDateTime desc;

    return DateTimeUtil::removeTimeZoneOffset(table.UtcDateTime,DateTimeUtil::getCompanyTimeZone());

}

[SysEntryPointAttribute]

public System.DateTime getSystemDateTime3()

{

    ReinhardTest_Table table;

    System.DateTime dt;

    utcDateTime utcDT;

    select table order by table.UtcDateTime desc;

    utcDT=DateTimeUtil::removeTimeZoneOffset(table.UtcDateTime,DateTimeUtil::getCompanyTimeZone());

    dt=Global::utcDateTime2SystemDateTime(utcDT);

    return dt;

}

[SysEntryPointAttribute]

public System.DateTime getStringDateTime4()

{

    ReinhardTest_Table table;

    str strDT;

    select table order by table.UtcDateTime desc;

    strDT = DateTimeUtil::toStr(table.UtcDateTime);

    return System.DateTime::Parse(strDT);

}

    这里,Reinhard同样选择了ReinhardTest_Table表中的最后一条记录,将其返回给DotNet,也就是2015-05-05 05:05:05那条。

    接着,在VS中,Reinhard调用这七个服务契约,看看他们返回给DotNet的Date
Time:

Image [2]

    Reinhard发现,只有GetUtcDateTime2和GetUtcDateTime3这个两个服务契约,给DotNet返回了正确的DateTime。

结论:正确的日期获取方式是GetUtcDateTime2和GetUtcDateTime3。

4、总结

    下面,Reinhard对通过AIF服务契约,进行DateTime存储、获取、比较的正确方式,进行总结。

4.1、DateTime存储









[SysEntryPointAttribute]

public void saveUtcDateTime( utcDateTime _utcDateTime)

{

    ReinhardTest_Table table;

    ttsBegin;

    table.UtcDateTime=_utcDateTime;

    table.insert();

    ttsCommit;

}

4.2、DateTime对比









[SysEntryPointAttribute]

public boolean compareUtcDateTime( utcDateTime _utcDateTime)

{

    ReinhardTest_Table table;

    select table order by table.UtcDateTime desc;

    return table.UtcDateTime==_utcDateTime;

}

4.3、DateTime获取









[SysEntryPointAttribute]

public utcDateTime getUtcDateTime2()

{

    ReinhardTest_Table table;

    select table order by table.UtcDateTime desc;

    return DateTimeUtil::applyTimeZoneOffset(table.UtcDateTime ,DateTimeUtil::getUserPreferredTimeZone());

}

[SysEntryPointAttribute]

public utcDateTime getUtcDateTime3()

{

    ReinhardTest_Table table;

    str strDT;

    select table order by table.UtcDateTime desc;

    return DateTimeUtil::applyTimeZoneOffset(table.UtcDateTime ,DateTimeUtil::getCompanyTimeZone());

}

    这次,Reinhard就分享到这里。如果同学们遇到什么问题,也欢迎和Reinhard沟通交流。

Site by Reinhard Hsu using Hexo & Random

Hide