Convert Persian Date String to Gregorian DateTime

To convert a Persian date string to a gregorian DateTime , I use date picker and it sends me a string like "۱۳۹۴/۰۲/۲۰"

 PersianCalendar p = new PersianCalendar(); string[] d = start.Split('/'); DateTime dt = new DateTime(int.Parse(d[0]), int.Parse(d[1]), int.Parse(d[2]), new HijriCalendar()); 

and my function, which is being converted,

 public static DateTime ToGregorianDate(this DateTime dt) { PersianCalendar pc = new PersianCalendar(); return pc.ToDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0, 0); } 

It gives a DateTime , how can I send the correct DateTime when it wants to convert, this error is displayed:

The input string was not in the correct format.

+6
source share
4 answers

You have two different problems:

  • Arabic numerals not supported by DateTime parsing

  • PersianCalendar not part of any CultureInfo , so you cannot use it directly to parse a string before DateTime (and you cannot set it to an existing CultureInfo ).

Possible Solution:

 string date = "۱۳۹۴/۰۲/۲۰"; string date2 = Regex.Replace(date, "[۰-۹]", x => ((char)(x.Value[0] - '۰' + '0')).ToString()); 

Replace Arabic to Decimal Numbers

 DateTime dt = DateTime.ParseExact(date2, "yyyy/MM/dd", CultureInfo.InvariantCulture); 

Then analyze the date that ignores the calendar.

 PersianCalendar pc = new PersianCalendar(); DateTime dt2 = pc.ToDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); 

Then convert the date to the desired calendar.

+5
source

As I commented; Eastern Arabic numbers are not supported by DateTime parsing methods; it accepts only Arabic numbers .

However, the char type has a GetNumericValue method that converts any Unicode numeric character to double .

Use a combination of the char.GetNumericValue , string.Join and Int32.Parse ;

 string d = "۱۳۹۴/۰۲/۲۰"; int year = Int32.Parse(string.Join("", d.Split('/')[0].Select(c => char.GetNumericValue(c)))); // 1394 int month = Int32.Parse(string.Join("", d.Split('/')[1].Select(c => char.GetNumericValue(c)))); // 2 int day = Int32.Parse(string.Join("", d.Split('/')[2].Select(c => char.GetNumericValue(c)))); // 20 

And then you can create a DateTime based on these values;

 DateTime dt = new DateTime(year, month, day); 

Then you can use;

 PersianCalendar pc = new PersianCalendar(); var dt1 = pc.ToDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Millisecond); // {10.05.2015 00:00:00} 
+5
source

You need to convert Persian digits to int * manually, for example.

  private static int ParsePersianNumber(String value) { int result = 0; // Persian digits are Unicode characters 0x06F0-0x06F9 foreach (var ch in value) result = result * 10 + ch - 0x06F0; return result; } ... String start = "۱۳۹۴/۰۲/۲۰"; PersianCalendar p = new PersianCalendar(); string[] d = start.Split('/'); // int.Parse -> ParsePersianNumber // dt == 14 Mar 1974 DateTime dt = new DateTime( ParsePersianNumber(d[0]), ParsePersianNumber(d[1]), ParsePersianNumber(d[2]), new HijriCalendar()); 
+3
source

First display the Arabic numerals:

 var mapToArabic = new Dictionary<char, char>{ {'۰', '0'}, {'۱', '1'}, {'۲', '2'}, {'۳', '3'}, {'۴', '4'}, {'۵', '5'}, {'۶', '6'}, {'۷', '7'}, {'۸', '8'}, {'۹', '9'}}; var p = new System.Globalization.PersianCalendar(); var start = "۱۳۹۴/۰۲/۲۰"; string[] persian = start.Split('/'); 

The main change in your source code: mapping from an array of Persian numbers (year, month, date) into an equivalent array containing values ​​in Arabic numbers:

 var arabic = persian .Select(persianWord => new string(persianWord .Select(persianChar => mapToArabic[persianChar]) .ToArray())) .ToList(); 

Now you can use this as before:

 DateTime dt = new DateTime(int.Parse(arabic[0]), int.Parse(arabic[1]), int.Parse(arabic[2]), new System.Globalization.HijriCalendar()); var pc = new System.Globalization.PersianCalendar(); var result = pc.ToDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0, 0); 
+2
source

Source: https://habr.com/ru/post/986269/


All Articles