doesn't work and raises an ArgumentOutOfRange exception. This article shows how to get rid of this.

Background

Although .NET provides both PersianCalendar and Persian CultureInfo, there are some issues in Persian culture that prevents the smooth use
of Persian culture. You can see the user complaints under the PersianCalendar
page on MSDN. The questions are:

How to set PersianCalendar on a DateTimeFormatInfo?

Why calendar resources such as month names are not correct and how to fix them?

Why Persian calendar is not included in the set of Optional Calendars in Persian culture?

These problems have already been noted by Reza Taroosheh in his great article
How to set PersianCalendar to CultureInfo. He also provides a PersianCalendarHelper class
to fix these issues based on Reflection. This class reasonably addresses the first two issues. It adds Persian month names and also sets the Persian calendar
on the DateTimeFormat. This normally suffices to have a working Persian culture for a .NET application.

But it fails to add the Persian calendar to the set of optional calendars. Troosheh suggests to install a new custom locale to solve this issue. In this article, a new approach
is introduced to fix the optional calendars issue.

Fixing Optional Calendars

Inspecting internal codes of CultureInfo by Reflection reveals that the array of optional calendars is actually read from a TableRecord structure
from the Windows stored locale data. The actual location of this array is back calculated, so that one can fix this array. Actually, the memory is in a protected area,
so that we should use the VirtualProtect API before trying to fix the array.

How to Use the Code

One may use the static methods of PersianCalendarHelper to fix the Persian culture. The simplest way is calling the FixAndSetCurrentCulture method
somewhere in application startup. This will set the current thread culture to a new fixed culture.

PersianCultureHelper.FixAndSetCurrentCulture();

Another approach will be using the FixPersianCulture method with the appropriate options. This way the programmer can control things to be fixed. For instance:

You are right. It's because I failed to recognize that waCalendarsFiled is null, if no call to OptionalCalendars is made prior to calling this method. In fact waCalendarsField gets initialized in call to CalendarIds property of culture data. So either force a call to OptionalCalendars before trying to call FixOptionalCalendars, something like this: CultureInfo actual; // Force OptionaCalendars call int i = culture.OptionalCalendars.Count; actual = PersianCultureHelper.FixOptionalCalendars(culture, 4); Assert.AreEqual(actual.OptionalCalendars[3].GetType() == typeof(PersianCalendar), false);