将字符串波斯日期转换为公历日期时间

Convert string Persian date to Gregorian DateTime

要将字符串波斯日期转换为公历 DateTime, 我使用日期时间选择器,它向我发送了一个字符串,例如 "۱۳۹۴/۰۲/۲۰"

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());

我的转换函数是

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);    
}

它给出了 DateTime 我怎样才能发送正确的 DateTime 当它想要转换时显示此错误:

Input string was not in a correct format.

您有两个不同的问题:

  • DateTime 解析不支持阿拉伯数字

  • PersianCalendar 不属于任何 CultureInfo,因此在将 string 解析为 DateTime 时不能直接使用它(并且您不能将其设置为预先存在的 CultureInfo).

可能的解决方案:

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

将阿拉伯数字替换为十进制数字

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

然后忽略日历解析日期

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

然后将日期转换为正确的日历。

您必须手动将波斯数字转换为 int *,例如

    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());

先映射到阿拉伯数字:

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('/');    

原始代码的主要变化:从波斯数字数组(年、月、日)映射到包含阿拉伯数字值的等效数组:

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

现在您可以像以前使用另一个一样使用它了:

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); 

正如我评论的那样; Eastern Arabic numerals does not supported by DateTime parsing methods, it only accepts Arabic numerals.

但是,char 类型有一个 GetNumericValue method,它将任何数字 Unicode 字符转换为 double

让我们结合使用 char.GetNumericValuestring.JoinInt32.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

然后你可以根据这个值创建一个DateTime

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

那你就可以用了;

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}