Search code examples
c#globalizationcultureinfodatetime-formatpersian

How to derive custom culture from .NET CultureInfo class?


I want to set my application culture to whatever I want, regardless of what the OS culture is. To obtain this I used CultureInfo class with "fa-IR" as culture, but it used the "GregorianCalendar" as default calendar and not the .NET PersianCalendar class. So I tried to derive a new class from CultureInfo to implement my customer culture:

/// <summary>
/// Represents culture specific information, Persian calendar and number format info for Iran.
/// </summary>
public class PersianCultureInfo : CultureInfo
{
    private Calendar _calendar = new PersianCalendar();

    public PersianCultureInfo()
        : base("fa-IR", true)
    {
    }

    /// <summary>
    /// Persian calendar with solar system algorithm for Iran.
    /// </summary>
    public override Calendar Calendar
    {
        get
        {
            return this._calendar;
        }
    }

    public static PersianCultureInfo Create()
    {
        PersianCultureInfo culture = new PersianCultureInfo();
        culture.PerpareDateTimeFormatInfo();
        return culture;
    }

    private void PerpareDateTimeFormatInfo()
    {
        this.DateTimeFormat.Calendar = this.Calendar;
        this.DateTimeFormat.FirstDayOfWeek = DayOfWeek.Saturday;
    }
}  

The problem is that the DateTimeFormat property throws the following exception:

Not a valid calendar for the given culture. 
Parameter name: value  

So I tried to override the OptionalCalendars property to add the PersianCalendar to them, because by default the list only contains the GregorianCalendar and HijriCalendar:

    public override Calendar[] OptionalCalendars
    {
        get
        {
            return base.OptionalCalendars.Concat<Calendar>(new Calendar[1] { new PersianCalendar() }).ToArray<Calendar>();
        }
    }  

But it didnt solved the problem. What is wrong? How can I set PersianCalendar as default calendar for CultureInfo and DateTimeFormat in correct way?


Solution

  • Five years have passed and things have changed since then. Microsoft has open sourced .NET, and now, it supports PersianCalendar out of the box.

    I have tried the following snippet with .NET Core 1.0 and it works just fine:

    using System;
    using System.Globalization;
    
    namespace ConsoleApplication
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                System.Globalization.CultureInfo.CurrentCulture = 
                    new CultureInfo("fa-IR");
                Console.WriteLine(System.DateTime.Now); 
                // Prints: 1395/4/19 A.D. 13:31:55  
            }
        }
    }