将字符串波斯日期转换为格里高利日期时间

时间:2015-04-30 06:06:36

标签: c# datetime calendar

要将字符串波斯日期转换为格里高利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 当它想要转换时显示此错误:

  

输入字符串的格式不正确。

4 个答案:

答案 0 :(得分:7)

您有两个不同的问题:

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

  • PersianCalendar不属于任何CultureInfo,因此在解析stringDateTime时您无法直接使用它(并且您无法将其设置为预先存在的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);

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

答案 1 :(得分:5)

正如我评论的那样; DateTime解析方法不支持Eastern Arabic numerals,它只接受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}

答案 2 :(得分:3)

您必须手动将波斯数字转换为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());

答案 3 :(得分:2)

首先映射到阿拉伯数字:

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