C# 用c解析ISO8601的基本格式和扩展格式#
就我所见,带有“o”和“s”参数的DateTime.ParseExact只能解析ISO 8601扩展格式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,
如何使用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