Reputation: 441
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
Upvotes: 2
Views: 977
Reputation: 176
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;
}
}
}
Upvotes: 1
Reputation: 441
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...
Upvotes: 2