最新消息:ww12345678 的部落格重装上线,希望大家继续支持。

[转]关于AX2012的Date、Time、UTCDateTime

网络文摘 William 2003浏览 0评论

.NET Interop X++一文中有简单提到在.NET interop中如何使用日期时间类型,这里着重看看X++中这些日期时间类型的区别。

创建一个表,包含类型分别为Date、Time和UTCDateTime的字段,如下使用JOB在表中插入数据:

static void DateTimeInsertJob(Args _args)
{
    utcDateTime utcdatetime1;
    TableTestDateTime ttd;
    date date1=24\09\2012;
    TimeOfDay time1=str2time("12:40:00");
    ;
    ttsBegin;
    delete_from ttd;

    ttd.DateLineID=1;
    ttd.FieldUTCDateTime=DateTimeUtil::newDateTime(date1,time1);
    ttd.FieldDate=date1;
    ttd.FieldTime=time1;
    ttd.insert();

    ttd.DateLineID=2;
    ttd.FieldUTCDateTime=DateTimeUtil::newDateTime(date1,time1,DateTimeUtil::getUserPreferredTimeZone());
    ttd.FieldDate=date1;
    ttd.FieldTime=time1;
    ttd.insert();

    ttd.DateLineID=3;
    utcdatetime1=DateTimeUtil::utcNow();
    ttd.FieldUTCDateTime=utcdatetime1;
    ttd.FieldDate=DateTimeUtil::date(ttd.FieldUTCDateTime);
    ttd.FieldTime=DateTimeUtil::time(ttd.FieldUTCDateTime);
    ttd.insert();


    ttd.DateLineID=4;
    utcdatetime1=DateTimeUtil::utcNow();
    ttd.FieldUTCDateTime=utcdatetime1;
    ttd.FieldDate=today();
    ttd.FieldTime=timeNow();
    ttd.insert();

    ttd.DateLineID=5;
    ttd.FieldUTCDateTime=DateTimeUtil::applyTimeZoneOffset(utcdatetime1,Timezone::GMTPLUS0545KATHMANDU);
    ttd.FieldDate=DateTimeUtil::date( ttd.FieldUTCDateTime);
    ttd.FieldTime=DateTimeUtil::time(ttd.FieldUTCDateTime);
    ttd.insert();


    ttsCommit;
}

我们从form上显示这些插入的纪录,得到的结果是:

第一行纪录,我们直接赋值一个日期到Date类型date1,从字符串得到一个TimeOfDay类型time1,然后使用DateTimeUtil::newDateTime(date1,time1)从这个Date和TimeofDay类型构建一个UTC日期时间类型,DateTimeUtil::newDateTime()的第三个参数可以指定一个时区,这里没有指定,默认使用了UTC的0时区,最后会发现显示在窗口的UTC时间比我们插入的时间晚了8个小时,这是因为form上的utcdatetime控件的“TimeZonePreference”属性设置为了“Auto”,它会自动使用当前用户的时区(北京时间+8时区)来显示这个UTC标准时间,如果改为“No conversion”则始终使用0时区的日期时间来显示。

第二行纪录使用了在构建UTC时间时使用了用户设置的时区参数DateTimeUtil::getUserPreferredTimeZone(),form显示的时间和TimeOfDay的时间是一致的。

第三行纪录从DateTimeUtil::utcNow()得到当前UTC日期时间,并从它得到一个timeofday时间-DateTimeUtil::time(ttd.FieldUTCDateTime),注意这个时间是UTC时间在0时区的时间部分,比form上显示的UTC当前时区时间早了8小时。

第四行纪录则是使用today()和timenow()两个函数来分别初始化Date日期和TimeOfDay时间,得到的是当前系统的日期时间,和显示的UTC当前时间是一致的。

第五行使用DateTimeUtil::applyTimeZoneOffset()对一个UTC日期时间做时区转换,转换后保存后重新显示的时间不再是插入纪录时的当时系统UTC时间。

注意UTC时间(世界协调时间)和格林威治时间不是一回事,前者基于世界原子时钟,后者基于地球自转,目前世界上的标准时间是UTC时间而不再是格林威治时间。

从上面的结果可以看到,在处理UTC时间时需要考虑到当前的时区,否则可能得到和预想不符的结果。再来看看保存在数据库中的数据:

首先可以看到保存在数据库中的Date是不纪录时间的;有一叫做FIELDUTCDATETIMEZID的字段,这是AOT表中看不到的隐藏字段,它在创建一个UTC字段的时候自动生成,用来保存UTC字段日期时间的时区及夏令时信息,第二条纪录我们手工指定了时区信息,所以该纪录的这个字段的值和其他纪录不同的,这个字段用来帮助我们在比如政府重新定义了所属时区、夏令时起始时更新保存在数据库中的UTC;timeofday在数据库中是以整数保存在数据库中的。

以上的测试基于windows系统的时区和AX用户option里设置的时区同在+8时区,如果我们把系统的时区改成其他其他时区,重启AX客户端程序会得到“Time zone mismatch”的提示信息(用户option->General->Time zone mismatch notification打勾的情况下),重新执行下JOB重填表纪录,会发现第四条纪录TimNow()得到的时间是当前时区显示的系统时间,而UTC时间仍然是正确的显示用户option定义的UTC时区时间,所以TimNow()是和当前系统时间一致受时区设置影响,而DateTimeUtil::utcNow()则不受时区设置影响

下一项测试是在一台Client机器上(不是AOS服务器)将日期设置提前一天来看看today()和DateTimeUtil::utcNow()是从客户机还是从AOS取值,测试的结果是两者都使用了当前Client的日期设置,得到的结果比AOS上的时间提前一天。

继续测试以下几个和System date有关的日期时间:

   info(date2str(today(),123,2,2,2,2,4));
   info(date2str(systemdateget(),123,2,2,2,2,4));
   info(date2str(DateTimeUtil::date(DateTimeUtil::getSystemDateTime()),123,2,2,2,2,4));
   info(date2str(DateTimeUtil::date(DateTimeUtil::applyTimeZoneOffset(DateTimeUtil::getSystemDateTime(), DateTimeUtil::getUserPreferredTimeZone())),123,2,2,2,2,4));

得到的结果是systemdateget()、DateTimeUntil::getSystemDateTime()得到的日期是设置在Tools->Session date and time下的日期时间

那如何得到AOS的系统时间呢?这似乎没有专门的类及方法来从AOS获取日期时间,其实是最简单的办法就是把today()、TimeNow()、DateTimeUntil::utcNow()放到Server去执行。

以上的测试比较凌乱,读者自行去总结吧,更多有关时区的内容可以参见http://msdn.microsoft.com/EN-US/library/cc622312.aspx

 

原文地址:http://www.cnblogs.com/duanshuiliu/archive/2012/09/24/2699922.html

 

转载请注明:ww12345678 的部落格 | AX Helper » [转]关于AX2012的Date、Time、UTCDateTime

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址