【问题标题】:PersianCalendar can't convert year/month/31(day) to standard datePersianCalendar 无法将年/月/31(天)转换为标准日期
【发布时间】:2014-07-02 18:16:34
【问题描述】:

我正在尝试将 persianDate 转换为 standarddate

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

Persiandate 的格式如下:1392/10/12(Year/month/day)

在我的应用程序中,我试图将 Year/month/31 转换为标准时间,但出现此错误:

{System.FormatException: String was not recognized as a valid DateTime.
   at System.DateTimeParse.ParseExactMultiple(String s, String[] formats, DateTimeFormatInfo dtfi, DateTimeStyles style)

我得到错误的确切值是1393/04/31

【问题讨论】:

  • 这个月有 31 天吗?
  • 如果你的意思是波斯语是的。波斯语中的某些月份有 31 天
  • 但是您尝试转换的月份是? “字符串未被识别为有效的日期时间”valid 是这里的关键词。
  • 是的,我尝试转换的时间是 1393/04/31>,正如我在问题中提到的那样
  • 看到这个应该有帮助stackoverflow.com/questions/10655116/…

标签: c# datetime datetime-format persian datetime-conversion


【解决方案1】:

Sergey 明确使用使用波斯历的文化的解决方案应该可行,但另一种选择是使用我的 Noda Time 库:

using System;
using System.Globalization;
using NodaTime;
using NodaTime.Text;

public class Test
{
    public static void Main()        
    {
        // Providing the sample date to the pattern tells it which
        // calendar to use.

        // Noda Time 2.0 uses a property instead of a method.
        // var calendar = CalendarSystem.Persian;           // 2.0+
        var calendar = CalendarSystem.GetPersianCalendar(); // 1.x

        LocalDate sampleDate = new LocalDate(1392, 10, 12, calendar);
        var pattern = LocalDatePattern.Create(
            "yyyy/M/d", CultureInfo.InvariantCulture, sampleDate);
        string text = "1393/04/31";
        ParseResult<LocalDate> parseResult = pattern.Parse(text);
        if (parseResult.Success)
        {
            LocalDate date = parseResult.Value;
            // Use the date
        }
    }    
}

DateTime 不同,这里的LocalDate 结果知道它只是一个日期(因此不会提供时间方面)并且还知道它在哪个日历系统中(因此您不需要继续调用像@ 这样的方法987654325@获取特定零件)。

请注意,yyyy/M/d 的解析模式将能够解析带有前导零的值,因此您不需要多个模式。如果您知道格式总是有两位数的月份和日期,但是,我会明确地使用yyyy/MM/dd

【讨论】:

    【解决方案2】:

    说明

    这里有几个问题:

    1. DateTime d1 = DateTime.ParseExact(persianDate, formats,
                                        CultureInfo.CurrentCulture, DateTimeStyles.None);
      

      CultureInfo.CurrentCulture 取决于机器。但是函数名是ConvertPersianToEnglish,这意味着ParseExactprovider参数应该设置为波斯日期格式提供者。

    2. 出于某种原因,伊朗 CultureInfo 实例将 GregorianCalendar 作为默认日历。此外,它在OptionalCalendars 中没有PersianCalendar。这很奇怪,因为 System.Globalization 命名空间包含 PersianCalendar 类。

    解决方案

    您可以在这里使用几个选项。

    解决方案 1

    this article Babak Mahmoudi 提供了一个帮助类,可以修复CultureInfo 实例以接受PersianCalendar。这个类中的方法不是很温和(在实现方面)。但它包含FixPersianDateTimeFormat 方法,这是非常无辜的。使用它,您的代码将如下所示:

    public static DateTime ConvertPersianToEnglish(string persianDate)
    {
        string[] formats = { "yyyy/MM/dd", "yyyy/M/d", "yyyy/MM/d", "yyyy/M/dd" };
        DateTimeFormatInfo persianDateTimeFormatInfo = new CultureInfo("fa-Ir").DateTimeFormat;
        PersianCultureHelper.FixPersianDateTimeFormat(persianDateTimeFormatInfo, true);
        return DateTime.ParseExact(persianDate, formats, persianDateTimeFormatInfo, DateTimeStyles.None);
    }
    

    解决方案 2

    您可以自己解析字符串,然后使用PersianCalendar.ToDateTime。在这里查看comecme的答案:How to convert Persian Calendar date string to DateTime?

    【讨论】:

      【解决方案3】:

      这是将波斯日期转换为 DateTime 的简单方法:

          public DateTime GetGregorianDate(string persianDate)
          {
              PersianCalendar persian_date = new PersianCalendar();
              var dateParts = GetDateParts(persianDate);
              DateTime dt = persian_date.ToDateTime(dateParts[0], dateParts[1], dateParts[2], 0, 0, 0, 0, 0);
              return dt;
          }
      
          public int[] GetDateParts(string persianDate)
          {
              return persianDate.Split('/').Select(datePart => int.Parse(datePart)).ToArray();
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-20
        • 1970-01-01
        • 2015-04-29
        • 1970-01-01
        相关资源
        最近更新 更多