Thursday, May 15, 2014

AXAPTA: Converting between UTCDateTime and current date time (current timezone)

AX stores date/time within database in UTC format and it might be different form what you get in AX Forms (DateEdit form's controls are basically responsible to show date/time in user defined time zone), specially when you are in different timezone, developers however need to do conversion more often, here the journey just began. ...among those resources which are available over the net to study AX time zone conversion, most of them not working properly and some of them utilize Global .NET conversion method in order to convert between UTC and current timezone  - which is not useful when you have multiple company accounts in AX.
By using from DateTimeUtil::newDateTime() class, developers are happy to overcome time zone conversion, however it's not as much as easy and straight forward that you assume, so lets see how to treat newDateTime method in order to get a working result in terms of conversion between time zones :
In the code below if you try to put getCompanyTimeZone() in newDateTime method you'll get dateTime + companyTimeZone not the difference!
ie, assuming a companyTimeZone is in PST (-8UTC), it will then show you utcNow+8 not utcNow-8 !
Having said that typically this method turned out to create a new instance of date/time in desired time zone so it's not a conversion method.
I used to make a time in companyTimeZone first, then making a date  in companyTimeZone and ultimately going forward with newDateTime with no offset information in order to convert between time zones;
By the way be aware of using newDateTime method to compare between UTC date/time in your own code.

static void JobUTC2TimeZone(Args _args)
{
    utcDateTime dateTime;
    date dateInCompanyTimeZone;
    TimeOfDay timeInCompanyTimeZone;
    ;
    dateTime = DateTimeUtil::utcNow();
    timeInCompanyTimeZone = DateTimeUtil::time(DateTimeUtil::applyTimeZoneOffset(dateTime, DateTimeUtil::getCompanyTimeZone()));
    dateInCompanyTimeZone = DateTimeUtil::date(DateTimeUtil::applyTimeZoneOffset(dateTime, DateTimeUtil::getCompanyTimeZone()));
    dateTime = DateTimeUtil::newDateTime(dateInCompanyTimeZone, timeInCompanyTimeZone);
    info(strfmt(datetime2str(dateTime)));
}

No comments: