2

I had a problem with DataGridView to show Date as the Persian calendar. After using this code:

using System.Globalization;
using System.Threading;

...

CultureInfo info = new CultureInfo("fa-Ir")
{
    DateTimeFormat = {Calendar = new PersianCalendar()}
};

Thread.CurrentThread.CurrentCulture = info;

My problem is solved, no problem occurs with my PC or Laptop both are Windows 10 and .netFramwork 4.8

My customer PC with Windows 7 has a problem with only Culture.. Why is that?

Exception Message : not a valid calendar for the given culture.parameter name: value

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Rasool Aghajani
  • 340
  • 2
  • 10
  • 2
    Possible duplicate of [Persian Calendar not valid with CultureInfo](https://stackoverflow.com/questions/5449085/persian-calendar-not-valid-with-cultureinfo) – peeyush singh Apr 23 '19 at 07:14
  • why in my laptop or Home PC worked as well ?? – Rasool Aghajani Apr 23 '19 at 08:00
  • As Microsoft docs say: "You cannot use a PersianCalendar object as the default calendar for a culture. The default calendar is specified by the CultureInfo.Calendar property and must be one of the calendars returned by the CultureInfo.OptionalCalendars property. Currently, the PersianCalendar class is not an optional calendar for any culture supported by the CultureInfo class and consequently cannot be a default calendar." It seems from Windows 10 and Windows Server 2019, they solved this problem. Read more here: https://docs.microsoft.com/en-us/dotnet/api/system.globalization.persiancalendar – Ali Dehghani Jun 16 '22 at 18:28

2 Answers2

1

I did replace my old code with this :

        System.Globalization.CultureInfo calture = new System.Globalization.CultureInfo("fa-Ir");
        System.Globalization.DateTimeFormatInfo info = calture.DateTimeFormat;
        info.AbbreviatedDayNames = new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" };
        info.DayNames = new string[] { "یکشنبه", "دوشنبه", "ﺳﻪشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" };
        info.AbbreviatedMonthNames = new string[] { "فروردین", "ارديبهشت", "خرداد", "تير", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
        info.MonthNames = new string[] { "فروردین", "ارديبهشت", "خرداد", "تير", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
        info.AMDesignator = "ق.ظ";
        info.PMDesignator = "ب.ظ";
        info.ShortDatePattern = "yyyy/MM/dd";
        info.FirstDayOfWeek = DayOfWeek.Saturday;
        System.Globalization.PersianCalendar cal = new System.Globalization.PersianCalendar();

        var field = typeof(System.Globalization.DateTimeFormatInfo).GetField("calendar", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        field?.SetValue(info, cal);
        var fieldInfo = typeof(System.Globalization.DateTimeFormatInfo).GetField("m_cultureTableRecord", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        if (fieldInfo != null)
        {
            object obj = fieldInfo.GetValue(info);
            var methodInfo = obj.GetType().GetMethod("UseCurrentCalendar", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            if (
                methodInfo !=
                null)
            {
                var propertyInfo = cal.GetType().GetProperty("ID", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                if (
                    propertyInfo !=
                    null)
                    methodInfo.Invoke(obj, new object[] { propertyInfo.GetValue(cal, null) });
            }
        }
        var field1 = typeof(System.Globalization.CultureInfo).GetField("calendar", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        field1?.SetValue(calture, cal);
        var fieldInfo1 = typeof(System.Globalization.CultureInfo).GetField("calendar", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        fieldInfo1?.SetValue(calture, cal);

        System.Threading.Thread.CurrentThread.CurrentCulture = calture;
        System.Threading.Thread.CurrentThread.CurrentUICulture = calture;
        System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat = info;
        System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat = info;

and it's worked as well in all computers... but I dunno .. if some code is true should be worked in all Computers! else if has a problem should not be worked in any computers...

Rasool Aghajani
  • 340
  • 2
  • 10
1

Based on Rasool Aghajani's answer, I've implemented a new CultureInfo class that you can set as the default culture of your application and all the date times will be in Persian culture format.

using System;
using System.Globalization;
using System.Reflection;

namespace SomeNamespace
{
    public class PersianCulture : CultureInfo
    {
        public PersianCulture() : base("fa-IR")
        {
            if (this.Calendar is PersianCalendar)
                return;

            //do hack here to set the default culture's calendar to PersianCalender on OS versions that are not supporting PersianCalendar as default culture calendar
            var dateTimeFormat = this.DateTimeFormat;

            dateTimeFormat.AMDesignator = "قبل‌ازظهر";
            dateTimeFormat.AbbreviatedDayNames = new string[] { "یکشنبه", "دوشنبه", "ﺳﻪشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" };
            dateTimeFormat.AbbreviatedMonthGenitiveNames = new string[] { "فروردین", "ارديبهشت", "خرداد", "تير", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
            dateTimeFormat.AbbreviatedMonthNames = new string[] { "فروردین", "ارديبهشت", "خرداد", "تير", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
            dateTimeFormat.CalendarWeekRule = CalendarWeekRule.FirstDay;
            dateTimeFormat.DateSeparator = "/";
            dateTimeFormat.DayNames = new string[] { "یکشنبه", "دوشنبه", "ﺳﻪشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" };
            dateTimeFormat.FirstDayOfWeek = DayOfWeek.Saturday;
            dateTimeFormat.FullDateTimePattern = "yyyy MMMM d, dddd H:mm:ss";
            dateTimeFormat.LongDatePattern = "yyyy MMMM d, dddd";
            dateTimeFormat.LongTimePattern = "H:mm:ss";
            dateTimeFormat.MonthDayPattern = "MMMM d";
            dateTimeFormat.MonthGenitiveNames = new string[] { "فروردین", "ارديبهشت", "خرداد", "تير", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
            dateTimeFormat.MonthNames = new string[] { "فروردین", "ارديبهشت", "خرداد", "تير", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
            dateTimeFormat.PMDesignator = "بعدازظهر";
            dateTimeFormat.ShortDatePattern = "yyyy/M/d";
            dateTimeFormat.ShortTimePattern = "H:mm";
            dateTimeFormat.ShortestDayNames = new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" };
            dateTimeFormat.TimeSeparator = ":";
            dateTimeFormat.YearMonthPattern = "yyyy MMMM";

            var persianCalendar = new PersianCalendar();

            var dateTimeFormatInfoCalendar = typeof(DateTimeFormatInfo).GetField("calendar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);

            dateTimeFormatInfoCalendar?.SetValue(dateTimeFormat, persianCalendar);

            var cultureTableRecord = typeof(DateTimeFormatInfo).GetField("m_cultureTableRecord", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            if (cultureTableRecord != null)
            {
                var dateTimeFormatValue = cultureTableRecord.GetValue(dateTimeFormat);

                var useCurrentCalendarMethodInfo = dateTimeFormatValue.GetType().GetMethod("UseCurrentCalendar", BindingFlags.NonPublic | BindingFlags.Instance);
                if (
                    useCurrentCalendarMethodInfo !=
                    null)
                {
                    var persianCalendarIdPropertyInfo = persianCalendar.GetType().GetProperty("ID", BindingFlags.Instance | BindingFlags.NonPublic);
                    if (
                        persianCalendarIdPropertyInfo !=
                        null)
                        useCurrentCalendarMethodInfo.Invoke(dateTimeFormatValue, new object[] { persianCalendarIdPropertyInfo.GetValue(persianCalendar, null) });
                }
            }

            var cultureCalendar = typeof(CultureInfo).GetField("calendar", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            cultureCalendar?.SetValue(this, persianCalendar);

            this.DateTimeFormat = dateTimeFormat;
        }
    }
}
Ali Dehghani
  • 176
  • 1
  • 6