在c#中解析基本和扩展格式的ISO 8601

时间:2013-12-03 02:32:29

标签: c# .net datetime iso8601 datetime-parsing

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

如何使用c#/ .Net?

解析ISO 8601基本格式和扩展格式

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

Iso8601Formats.DateAndOrTime 静态属性可能是此类中最有用的。使用代码:

DateTimeOffset.ParseExact("1985-04-12T10:22:00Z", Iso8601Formats.DateAndOrTime, CultureInfo.InvariantCulture, DateTimeStyles.None);

我能够解析以下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