C# 用c解析ISO8601的基本格式和扩展格式#

C# 用c解析ISO8601的基本格式和扩展格式#,c#,.net,datetime,iso8601,datetime-parsing,C#,.net,Datetime,Iso8601,Datetime Parsing,就我所见,带有“o”和“s”参数的DateTime.ParseExact只能解析ISO 8601扩展格式 如何使用c#/.Net解析ISO 8601基本格式和扩展格式?只需传递一个您希望允许的格式数组 string[] formats = new[] {"o","s","yyyyMMddHHmmss"}; // whatever you want DateTime dt = DateTime.ParseExact(yourDateString, formats,

就我所见,带有“o”和“s”参数的DateTime.ParseExact只能解析ISO 8601扩展格式


如何使用c#/.Net解析ISO 8601基本格式和扩展格式?

只需传递一个您希望允许的格式数组

string[] formats = new[] {"o","s","yyyyMMddHHmmss"}; // whatever you want
DateTime dt = DateTime.ParseExact(yourDateString, formats,
                                  CultureInfo.InvariantCulture,
                                  DateTimeStlyes.None);

下面是我最终创建的用于解析基本格式和扩展格式的类:

static class Iso8601Formats
{
    /// <summary>
    /// Represents ISO 8601 extended time format.
    /// </summary>
    public static readonly string[] TimeExtended;

    /// <summary>
    /// Represents ISO 8601 basic time format.
    /// </summary>
    public static readonly string[] TimeBasic;

    /// <summary>
    /// Represents ISO 8601 both basic and extended time format.
    /// </summary>
    public static readonly string[] Time;


    /// <summary>
    /// Represents ISO 8601 extended date format.
    /// </summary>
    public static readonly string[] DateExtended;

    /// <summary>
    /// Represents ISO 8601 basic date format.
    /// </summary>
    public static readonly string[] DateBasic;

    /// <summary>
    /// Represents ISO 8601 both basic and extended time format.
    /// </summary>
    public static readonly string[] Date;


    /// <summary>
    /// Represents ISO 8601 extended date and time format.
    /// </summary>
    public static readonly string[] DateAndTimeExtended;

    /// <summary>
    /// Represents ISO 8601 basic date and time format.
    /// </summary>
    public static readonly string[] DateAndTimeBasic;

    /// <summary>
    /// Represents ISO 8601 both basic and extended date and time format.
    /// </summary>        
    public static readonly string[] DateAndTime;

    /// <summary>
    /// Represents ISO 8601 extended date and/or time format.
    /// </summary>
    public static readonly string[] DateAndOrTimeExtended;

    /// <summary>
    /// Represents ISO 8601 basic date and/or time format.
    /// </summary>
    public static readonly string[] DateAndOrTimeBasic;

    /// <summary>
    /// Represents ISO 8601 both basic and extended date and/or time format.
    /// </summary>
    public static readonly string[] DateAndOrTime;

    static Iso8601Formats()
    {
        // date format extended
        IList<string> dateExtended = new List<string>{
                                      "yyyy'-'MM'-'dd"  // 1985-04-12
                                  };
        DateExtended = dateExtended.ToArray();

        // date format basic
        IList<string> dateBasic = new List<string>{
                                      "yyyyMMdd"        // 19850412
                                      ,"yyyy'-'MM"      // 1985-04
                                      ,"yyyy"           // 1985
                                      ,"'--'MMdd"       // --0412
                                      ,"'---'dd"        // ---12
                                  };
        DateBasic = dateBasic.ToArray();

        // date both basic and extended format
        List<string> date = new List<string>();
        date.AddRange(dateBasic);
        date.AddRange(dateExtended);
        Date = date.ToArray();


        // time format extended
        IList<string> timeExtended = new List<string>{                                          
                                      "HH':'mm':'sszzz"       // 10:22:00-0800
                                      ,"HH':'mm':'sszz"       // 10:22:00-08
                                      ,"HH':'mm':'ssZ"        // 10:22:00Z
                                      ,"HH':'mm':'ss"         // 10:22:05
                                      ,"HH':'mm"              // 10:22
                                      ,"HH"                   // 10
                                      ,"'-:'mm':'ss"          // -22:07
                                      ,"'-:-:'ss"             // -:-:07
        };
        TimeExtended = timeExtended.ToArray();

        // time format basic
        IList<string> timeBasic = new List<string>{                                          
                                      "HHmmsszzz"       // 102200-0800
                                      ,"HHmmsszz"       // 102200-08
                                      ,"HHmmssZ"        // 102200Z
                                      ,"HHmmss"         // 102205
                                      ,"HHmm"           // 1022
                                      ,"HH"             // 10
                                      ,"'-'mmss"        // -2207
                                      ,"'--'ss"         // --07
                                  };
        TimeBasic = timeBasic.ToArray();


        // time format both basic and extended
        List<string> time = new List<string>();
        time.AddRange(timeBasic);
        time.AddRange(timeExtended);
        Time = time.ToArray();


        // date-time basic
        IList<string> dateTimeBasic = 
            CombineFormats(dateBasic, timeBasic);
        DateAndTimeBasic = dateTimeBasic.ToArray();

        // date-time extended
        IList<string> dateTimeExtended = 
            CombineFormats(dateExtended, timeExtended);
        DateAndTimeExtended = dateTimeExtended.ToArray();

        // date-time both basic and extended
        List<string> dateTime = new List<string>();
        dateTime.AddRange(dateTimeBasic);
        dateTime.AddRange(dateTimeExtended);
        DateAndTime = dateTime.ToArray();


        // date-and-or-time basic format
        List<string> dateAndOrTimeBasic = new List<string>();
        dateAndOrTimeBasic.AddRange(dateTimeBasic);
        dateAndOrTimeBasic.AddRange(dateBasic);
        foreach (string timeFormat in timeBasic)
        {
            dateAndOrTimeBasic.Add("'T'" + timeFormat);
        }
        DateAndOrTimeBasic = dateAndOrTimeBasic.ToArray();

        // date-and-or-time extended format
        List<string> dateAndOrTimeExtended = new List<string>();
        dateAndOrTimeExtended.AddRange(dateTimeExtended);
        dateAndOrTimeExtended.AddRange(dateExtended);
        foreach (string timeFormat in timeExtended)
        {
            dateAndOrTimeExtended.Add("'T'" + timeFormat);
        }
        DateAndOrTimeExtended = dateAndOrTimeExtended.ToArray();


        // date-and-or-time basic and extended format
        List<string> dateAndOrTime = new List<string>();
        dateAndOrTime.AddRange(dateAndOrTimeBasic);
        dateAndOrTime.AddRange(dateAndOrTimeExtended);
        DateAndOrTime = dateAndOrTime.ToArray();
    }

    /// <summary>
    /// Produces all combinations of date and time formats
    /// </summary>
    /// <param name="dates">List of dates formats</param>
    /// <param name="times">List of time formats</param>
    private static IList<string> CombineFormats(IList<string> dates, IList<string> times)
    {
        List<string> dt = new List<string>();
        foreach (string dateFormat in dates)
        {
            foreach (string timeFormat in times)
            {
                // year/month must be present if time zone is specified
                if (dateFormat.StartsWith("'-") && (timeFormat.IndexOfAny(new[] { 'z', 'Z' }) != -1))
                    continue;

                dt.Add(dateFormat + "'T'" + timeFormat);
            }
        }
        return dt;
    }
}
我能够解析以下ISO 8601日期/时间:

19850412
1985-04
1985
--0412
---12
1985-04-12
T102205
T1022
T10
T-2207
T--07
T102200Z
T102200-08
T102200-0830
T10:22:05
T10:22
T10
T-:22:07
T-:-:07
T10:22:00Z
T10:22:00-08
T10:22:00-0830
19850412T102205
19850412T1022
19850412T10
19850412T-2207
19850412T--07
19850412T102200Z
19850412T102200-08
19850412T102200-0830
1985-04T102205
1985-04T1022
1985-04T10
1985-04T-2207
1985-04T--07
1985-04T102200Z
1985-04T102200-08
1985-04T102200-0830
1985T102205
1985T1022
1985T10
1985T-2207
1985T--07
1985T102200Z
1985T102200-08
1985T102200-0830
--0412T102205
--0412T1022
--0412T10
--0412T-2207
--0412T--07
---12T102205
---12T1022
---12T10
---12T-2207
---12T--07
1985-04-12T10:22:05
1985-04-12T10:22
1985-04-12T10
1985-04-12T-:22:07
1985-04-12T-:-:07
1985-04-12T10:22:00Z
1985-04-12T10:22:00-08
1985-04-12T10:22:00-0830
但是,此类仍然无法分析指定时区且没有年份的日期/时间,例如:

--0412T102200Z
--0412T102200-08
--0412T102200-0830

一些建设性的批评:1)这门课可能会达到你的目标,但效率相当低。由于最终结果总是相同的,您最好在静态类中有一些常量。2) 为什么要将这么多不同的输入解析成一个结果?你可能会得到一些结果,但人们会为了特定的目的要求特定的输入。例如,如果有人只提供
“T10:22:07”
,结果可能有该时间,但也有今天的日期和本地计算机的偏移量。在这一点上,您不能仅仅将其视为一个
DateTimeOffset
,您只需要查看时间组件,但现在您就可以知道这一点了。3) 如果你打算做任何像这样复杂的事情,你可能只想看看。有很多这样的细微差别会困住你。野田佳彦时间迫使你走上一条避免陷阱的道路。4) 祝你好运!我需要解析这么多类型的日期/时间格式,因为这是vCard RFC 6350和RFC 2426指定的,我需要实现。我正在解析的字段可以是基本格式或扩展格式的日期、时间或日期+时间。感谢您的节点时间参考。我很快看了看,它似乎只支持一种扩展格式:是的,您可以将所有这些日期和时间格式化程序字段设置为常量。但是初始化数组将非常大(仅日期和时间为64)。将会有成吨的副本,这将是相当困难的支持这样的类。添加对单一新格式的支持将需要在许多地方进行更改。
--0412T102200Z
--0412T102200-08
--0412T102200-0830