Quantcast
Channel: Microsoft Dynamics 365 Community
Viewing all articles
Browse latest Browse all 59438

Fixing firstDayOfWeek and firstWeekOfYear in AX2012

$
0
0
I was asked to have a look at why the date picker in AX still chose Sunday while the user expected Monday. I remember fixing this back in AX2009, so I was curious to see how this was solved in AX2012. The Global class and the methods firstDayOfWeek and firstWeekOfYear caught my attention. One of them used the current users language as key to find the best possible calendar setting, while the other picked the default system setting. Well, let us rewrite this and make it work a bit better, and since sharing is caring - here is how I solved it.

Global::firstWeekOfYear served as an inspiration, but I want it to differentiate between whatever languages my environment is serving. I can live with one cached result for each language, and the performance penalty is low and acceptable.



static int firstWeekOfYear()
{
#WinAPI
SysGlobalCache cache = classfactory.globalCache();
int clientFirstWeekOfYear;
anytype calendarWeekRuleValue;
// Axdata.Skaue ->
/*
str language;
*/
str language = currentUserLanguage();
// Axdata.Skaue
System.Globalization.CultureInfo userCulture;
System.Globalization.CalendarWeekRule calendarWeekRule;
System.Globalization.DateTimeFormatInfo userDateTimeFormat;

// Axdata.Skaue ->
/*
if (cache.isSet(classStr(Global), funcName()))
*/
if (cache.isSet(classStr(Global), funcName() + language))
// Axdata.Skaue
{
// Axdata.Skaue ->
/*
clientFirstWeekOfYear = cache.get(classStr(Global), funcName());
*/
clientFirstWeekOfYear = cache.get(classStr(Global), funcName() + language);
// Axdata.Skaue
}
else
{
// Axdata.Skaue ->
/*
language = currentUserLanguage();
*/
// Axdata.Skaue
userCulture = new System.Globalization.CultureInfo(language);
userDateTimeFormat = userCulture.get_DateTimeFormat();
calendarWeekRule = userDateTimeFormat.get_CalendarWeekRule();
calendarWeekRuleValue = CLRInterop::getAnyTypeForObject(calendarWeekRule);

switch(calendarWeekRuleValue)
{
case CLRInterop::getAnyTypeForObject(System.Globalization.CalendarWeekRule::FirstDay) :
clientFirstWeekOfYear = 0;
break;
case CLRInterop::getAnyTypeForObject(System.Globalization.CalendarWeekRule::FirstFullWeek) :
clientFirstWeekOfYear = 1;
break;
case CLRInterop::getAnyTypeForObject(System.Globalization.CalendarWeekRule::FirstFourDayWeek) :
clientFirstWeekOfYear = 2;
break;
}

// Axdata.Skaue ->
/*
cache.set(classStr(Global), funcName(),clientFirstWeekOfYear);
*/
cache.set(classStr(Global), funcName() + language,clientFirstWeekOfYear);
// Axdata.Skaue
}

return clientFirstWeekOfYear;
}


Using the same ideas, I changed Global::firstDayOfWeek. Again, I allowed for one cached result for each language.

static int firstDayOfWeek()
{
// Axdata.Skaue ->
/*
System.Globalization.DateTimeFormatInfo fi;
*/
int dow;
str language = currentUserLanguage();
System.Globalization.CultureInfo userCulture;
System.Globalization.DateTimeFormatInfo userDateTimeFormat;
// Axdata.Skaue

SysGlobalCache cache = classfactory.globalCache();
int clientFirstDayOfWeek;

// Axdata.Skaue ->
/*
if (cache.isSet(classStr(Global), funcName()))
*/
if (cache.isSet(classStr(Global), funcName() + language))
// Axdata.Skaue
{
// Axdata.Skaue ->
/*
clientFirstDayOfWeek = cache.get(classStr(Global), funcName());
*/
clientFirstDayOfWeek = cache.get(classStr(Global), funcName() + language);

}
else
{
// Axdata.Skaue ->
userCulture = new System.Globalization.CultureInfo(language);
userDateTimeFormat = userCulture.get_DateTimeFormat();
dow = userDateTimeFormat.get_FirstDayOfWeek();
/* Removed
fi = new System.Globalization.DateTimeFormatInfo();
dow = fi.get_FirstDayOfWeek();
*/
// Axdata.Skaue

// The .NET API returns 0 for sunday, but we expect sunday to
// be represented as 6, (monday is 0).
clientFirstDayOfWeek = (dow + 6) mod 7;

// Axdata.Skaue ->
/*
cache.set(classStr(Global), funcName(),clientFirstDayOfWeek);
*/
cache.set(classStr(Global), funcName() + language,clientFirstDayOfWeek);
// Axdata.Skaue
}

return clientFirstDayOfWeek;
}

So, for those of you who have an environment supporting potential multiple calendar setups, I recommend applying the fix above, or write your own fix. If you know a more efficient and better way, please comment below.

Viewing all articles
Browse latest Browse all 59438

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>