首页 文章

如何将 Persian Calendar 日期字符串转换为 DateTime?

提问于
浏览
15

我使用这些代码转换当前日期时间,并使用用户在文本框中键入的日期时间减去它。但它在转换时会出错。

PersianCalendar p = new System.Globalization.PersianCalendar();
DateTime date = new DateTime();
date = DateTime.Parse(DateTime.Now.ToShortDateString());
int year = p.GetYear(date);
int month = p.GetMonth(date);
int day = p.GetDayOfMonth(date);
string str = string.Format("{0}/{1}/{2}", year, month, day);
DateTime d1 = DateTime.Parse(str);
DateTime d2 = DateTime.Parse(textBox9.Text);
string s = (d2 - d1).ToString().Replace(".00:00:00", "");
textBox10.Text = (d2 - d1).ToString().Replace(".00:00:00","");

将日期时间从字符串转换为日期时,此行将出错:DateTime d1 = DateTime.Parse(str);

请帮我解决这个问题。

提前致谢

10 回答

  • 14

    无需在此处解析日期。

    编辑:

    最初我只想用这个答案指出 OP 处理中的错误。但我认为一个完整的答案会更好(尽管延迟:))并且是的我知道中间日期表示看起来不像波斯日期。但它不是需要的。此代码在当前日期和用户输入日期之间给出了适当的区别。

    string userInput = "1394/02/31";
    System.DateTime date = System.DateTime.Today;
    System.Globalization.PersianCalendar p = new System.Globalization.PersianCalendar();
    
    int year = p.GetYear(date);
    int month = p.GetMonth(date);
    int day = p.GetDayOfMonth(date);
    System.DateTime currentDate = new System.DateTime(year, month, 1);
    currentDate = currentDate.AddDays(day - 1);
    
    // validation omitted
    System.String[] userDateParts = userInput.Split(new[] { "/" }, System.StringSplitOptions.None);
    int userYear = int.Parse(userDateParts[0]);
    int userMonth = int.Parse(userDateParts[1]);
    int userDay = int.Parse(userDateParts[2]);
    System.DateTime userDate = new System.DateTime(userYear, userMonth, 1);
    userDate = userDate.AddDays(userDay - 1);
    
    System.TimeSpan difference = currentDate.Subtract(userDate);
    
  • 10

    只需在PersianCalendar类上使用ToDateTime方法:

    PersianCalendar p = new PersianCalendar();
    DateTime now = DateTime.Now;
    DateTime dateT = p.ToDateTime(now.Year, now.Month, now.Day, 0, 0, 0, 0);
    

    然后以这种格式获取字符串,只需:

    string str = dateT.ToShortDateString();
    
  • 9

    实际问题似乎在于解析用户以波斯日历格式输入的日期。因此,如果用户输入1391/2/31,您希望能够解析它。今天(2012 年 5 月 19 日)是1391/2/30所以你最终想要显示像1 day remaining这样的东西。

    这个问题有之前被问过。但是,那里接受的答案只是试图使用

    string persianDate = "1390/02/07";
    CultureInfo persianCulture = new CultureInfo("fa-IR");
    DateTime persianDateTime = DateTime.ParseExact(persianDate, 
        "yyyy/MM/dd", persianCulture);
    

    这对于像1391/2/31这样的日期不起作用。所以我认为你必须自己实现解析。

    如果没有实现任何错误检查,并假设用户始终使用yyyy/mm/dd格式,您可以使用:

    // Convert Persian Calendar date to regular DateTime
    var persianDateMatch = System.Text.RegularExpressions.Regex.Match(
        persianTargetTextBox.Text, @"^(\d+)/(\d+)/(\d+)$");
    var year = int.Parse(persianDateMatch.Groups[1].Value);
    var month = int.Parse(persianDateMatch.Groups[2].Value);
    var day = int.Parse(persianDateMatch.Groups[3].Value);
    var pc = new System.Globalization.PersianCalendar();
    var target = pc.ToDateTime(year, month, day, 0, 0, 0, 0);
    
    var difference = target - DateTime.Today;
    differenceLabel.Text = difference.TotalDays.ToString("0");
    

    您需要检查正则表达式是否真的找到了匹配项。您还必须检查pc.ToDateTime是否不会引发错误。不幸的是,似乎没有像波斯日历那样的DateTime.TryParse

    无论如何,你今天不需要解析为波斯日历,你只需要解析用户输入。

    您可能也对波斯图书馆 - 使用日期,日历和 DatePickers感兴趣,即使该文章非常陈旧(2007)。

  • 6

    我解决了这个问题。这是因为在某些月份有例外,所以如果你想减去彼此的两个日期时间,你应该将两者都转换为公历,然后你可以减去它们并看到结果。

    这是代码:

    PersianCalendar p = new PersianCalendar();
            string PersianDate1 = textBox1.Text;
            string[] parts = PersianDate1.Split('/', '-');
            DateTime dta1 = p.ToDateTime(Convert.ToInt32(parts[0]), Convert.ToInt32(parts[1]), Convert.ToInt32(parts[2]), 0, 0, 0, 0);
            string PersianDate2 = textBox2.Text;
            string[] parts2 = PersianDate2.Split('/', '-');
            DateTime dta2 = p.ToDateTime(Convert.ToInt32(parts2[0]), Convert.ToInt32(parts2[1]), Convert.ToInt32(parts2[2]), 0, 0, 0, 0);
            string s = (dta2 - dta1).ToString().Replace(".00:00:00", "");
            textBox3.Text = s; // Show the result into the textbox
    
  • 5

    这是您的朋友的文档:

    PersianCalendar 类

    DateTime 构造函数(Int32,Int32,Int32,日历)

    这是您需要的确切代码:

    PersianCalendar p = new System.Globalization.PersianCalendar();
    DateTime today = DateTime.Today;
    DateTime pDate = new DateTime(p.GetYear(today), p.GetMonth(today), p.GetDayOfMonth(today), p);
    DateTime d2 = DateTime.Parse(textBox9.Text);
    // THIS NEEDS TO BE EXPLAINED
    textBox10.Text = (d2 - pDate).ToString().Replace(".00:00:00","");
    

    最终,你想做什么?您在textBox10期待的结果是什么?如果你想要两个日期之间的天数,那么只需做(d2 - pDate).ToString("d")就可以得到天数的差异。也许如果你进一步解释你想要做什么,而不是你想要做什么,我们可以帮助你进一步。

    编辑:刚刚意识到了来自于什么。导致问题的那一行在这里:

    DateTime d2 = DateTime.Parse(textBox9.Text);
    

    相反,我们需要将其更改为也使用文化信息:

    CultureInfo persianCulture = new CultureInfo("fa-IR");
    DateTime d2 = DateTime.Parse(textBox9.Text, persianCulture)
    

    编辑:您是对的,它只允许以波斯语格式解析日期,但不会根据特定日历进行验证。为了使其正常工作,您将不得不手动解析日期并使用提供的 PersianCalendar 实例化新的 DateTime:

    DateTime d2;
    if(Regex.IsMatch(textBox9.Text, "^dddd/dd/dd$"))
    {
        d2 = new DateTime(
            int.Parse(textBox9.Substring(0,4)), 
            int.Parse(textBox9.Substring(5, 2)), 
            int.Parse(textBox9.Substring(8, 2)),
            p);
    }
    

    您只需确保输入与您指定的格式完全匹配,否则无法一致地解析 DateTime。

  • 1

    您可以使用此代码:

    DateTime today = DateTime.Today; // excludes h/m/s
    
      DateTime userdate = DateTime.Parse(textBox9.Text);
    

    如果你从另一个中减去一个,你得到一个 TimeSpan。

    TimeSpan diff = today - userDate;
    

    您可以使用此时间范围的属性以您喜欢的方式显示它们。

    要管理转换 form/to 波斯日历,您可以在此处找到一个很好的解决方案:

    .NET 如何将 Persian(Jalali 日历)的日期字符串解析为 DateTime 对象?

    参考文献:

    DateTime.Today

    时间跨度

  • 1

    这是我正在使用的代码:

    public DateTime ConvertPersianToEnglish(string persianDate)
            {
                string[] formats = { "yyyy/MM/dd", "yyyy/M/d", "yyyy/MM/d", "yyyy/M/dd" };
                DateTime d1 = DateTime.ParseExact(persianDate, formats,
                                                  CultureInfo.CurrentCulture, DateTimeStyles.None);
                PersianCalendar persian_date = new PersianCalendar();
                DateTime dt = persian_date.ToDateTime(d1.Year, d1.Month, d1.Day, 0, 0, 0, 0, 0);
                return dt;
            }
    
  • 1

    使用野田时间可以更轻松地完成此操作:

    using System.Globalization;
    using NodaTime;
    using NodaTime.Text;
    
    ...
    
    CultureInfo culture = CultureInfo.CreateSpecificCulture("fa-IR");
    CalendarSystem calendar = CalendarSystem.GetPersianCalendar();
    LocalDate template = new LocalDate(1, 1, 1, calendar);
    LocalDatePattern pattern = LocalDatePattern.Create("yyyy/M/d", culture, template);
    LocalDate result = pattern.Parse("1391/2/30").Value;
    
    // if you need a DateTime, then:
    DateTime dt = result.AtMidnight().ToDateTimeUnspecified();
    
  • 1

    您还可以使用以下.net 库来像使用 DateTime 一样简单地使用 PersianCalendar:

    C#中的波斯语 Calendar(PersianDateTime)

    var persianDateTime = PersianDateTime.Now;
    persianDateTime.EnglishNumber = true;
    Console.Write(persianDateTime.ToString());
    
  • 0

    试试这段代码:这段代码是由“grzegorz W”发布的编辑代码,但是他的代码生成错误,例如当用户输入日期=“1394/06/31”并且错误是“年,月,日参数描述 un-representable DateTime”时

    下面的代码是好的:

    string userInput = "1394/02/31";
    System.DateTime date = System.DateTime.Today;
    System.Globalization.PersianCalendar p = new System.Globalization.PersianCalendar();
    
    int year = p.GetYear(date);
    int month = p.GetMonth(date);
    int day = p.GetDayOfMonth(date);
    System.DateTime currentDate = new System.DateTime(year, month, day,p);
    
    System.String[] userDateParts = userInput.Split(new[] { "/" },      System.StringSplitOptions.None);
    int userYear = int.Parse(userDateParts[0]);
    int userMonth = int.Parse(userDateParts[1]);
    int userDay = int.Parse(userDateParts[2]);
    System.DateTime userDate = new System.DateTime(userYear, userMonth, userDay,p);
    
    System.TimeSpan difference = currentDate.Subtract(userDate);
    

相关问题