如何从.NET CultureInfo类派生自定义文化?

Meh*_*ghi 6 c# globalization cultureinfo persian datetime-format

我想将我的应用文化设置为我想要的任何东西,无论操作系统文化是什么.为了获得这个,我使用了"fa-IR"作为文化的CultureInfo类,但它使用"GregorianCalendar"作为默认日历而不是.NET PersianCalendar类.所以我试图从CultureInfo派生一个新类来实现我的客户文化:

/// <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;
    }
}  
Run Code Online (Sandbox Code Playgroud)

问题是DateTimeFormat属性抛出以下异常:

Not a valid calendar for the given culture. 
Parameter name: value  
Run Code Online (Sandbox Code Playgroud)

所以我试图覆盖OptionalCalendars属性以向它们添加PersianCalendar,因为默认情况下列表只包含GregorianCalendar和HijriCalendar:

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

但它没有解决问题.怎么了?如何以正确的方式将PersianCalendar设置为CultureInfo和DateTimeFormat的默认日历?

PHe*_*erg 5

尝试使用CultureAndRegionInfoBuilder.根据MSDN,这是创建自定义文化的首选方式.

编辑:如果失败,我想使用反射的脏解决方法是创建这种自定义文化的唯一方法.


Meh*_*ghi 4

五年过去了,事情发生了变化。Microsoft 已经开源了 .NET,现在它支持PersianCalendar开箱即用。

我已经在 .NET Core 1.0 中尝试了以下代码片段,它工作得很好:

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  
        }
    }
}
Run Code Online (Sandbox Code Playgroud)