How to derive custom culture from .NET CultureInfo class?
Asked Answered
B

3

7

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?

Borlow answered 15/2, 2011 at 9:39 Comment(1)
maybe this link help you more Compatriot:) codeproject.com/Articles/17495/Persian-DateTimePedagogics
B
4

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  
        }
    }
}
Borlow answered 9/7, 2016 at 13:41 Comment(0)
F
5

Try using a CultureAndRegionInfoBuilder. According to the MSDN this is the preferred way of creating custom cultures.

EDIT: If this fails I guess that a dirty workaround using reflection is the only way to create such a custom culture.

Flashy answered 16/2, 2011 at 8:9 Comment(2)
Thank you, I will try both ways as soon as possible. But I prefer not to use reflection here, because it is really a dirty workaround.Borlow
I tried the builder, there are some limitations in .NET framework for using PersianCalendar but these two solutions seems to work fine for my problem. The reflection way also works, but some strange behaviors occurs. After applying reflection trick and setting the new culture, When you call ToString of a DateTime instance you get Persian date but if you get the Year, Month and Day properties separately, you will get all in Gregorian dates.Borlow
B
4

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  
        }
    }
}
Borlow answered 9/7, 2016 at 13:41 Comment(0)
C
0

Unfortunately it is not possible. It has been filed as a bug so Microsoft is aware of this issue. See http://connect.microsoft.com/VisualStudio/feedback/details/507262/persian-cultureinfo

Carlotacarlotta answered 16/2, 2011 at 17:26 Comment(1)
Yes, I knew about those limitations, so I started this question to find a way to implement it by inheriting CultureInfo and Overrinding Calendar property.Borlow

© 2022 - 2024 — McMap. All rights reserved.