如何在c#中解析未知的日期时间格式

时间:2014-05-02 17:57:30

标签: c# parsing date datetime undefined

我正在尝试为TV Schedule Pro(http://sourceforge.net/p/tvschedulerpro)编写XML解析器。 一个特别的挑战是解析由日期元素报告的DateTime。

根据DTD文件:

  

此DTD中的所有日期和时间遵循相同的格式,基于松散   在ISO 8601.它们可以是'YYYYMMDDhhmmss'或一些初始子串,   例如,如果您只知道年份和月份,您可以拥有“YYYYMM”。   您还可以在最后添加时区;如果没有明确的时区   给定,假设为UTC。示例:'200007281733 BST','200209',   '19880523083000 +0300'。 (BST == +0100。)

这是一个充满挑战的情况,我最初考虑使用DateTimeFormatInfo.GetAllDateTimePatterns并使用DateTime.TryParseExact,关于时区的最后一行和任何分隔符的特定格式使得无法使用上述内容。

是否有一种简洁的方法来解析上述日期时间规范,或者只需要保持查找/添加各种模式来解析字符串,就像找到它们一样(看起来几乎是无穷无尽的组合)

2 个答案:

答案 0 :(得分:2)

好吧,您可以使用K格式说明符执行此类操作(有关详细信息,请参阅自定义日期时间格式字符串):

public static DateTimeOffset parseIso8601CompactForm( string text )
{
  DateTimeStyles options = DateTimeStyles.AllowWhiteSpaces
                         | DateTimeStyles.AssumeLocal
                         ;
  DateTimeOffset value = DateTimeOffset.ParseExact( text , formats , CultureInfo.CurrentCulture , options ) ;
  return value ;
}
static readonly string[] formats =
{
  "yyyyMMddHHmmssK" , "yyyyMMddHHmmss" ,
  "yyyyMMddHHmmK"   , "yyyyMMddHHmm"   ,
  "yyyyMMddHHK"     , "yyyyMMddHH"     ,
  "yyyyMMddK"       , "yyyyMMdd"       ,
  "yyyyMMK"         , "yyyyMM"         ,
  "yyyyK"           , "yyyy"           ,
} ;

但是你可能会发现这样的东西更具性能:

public static DateTimeOffset parseIso8601CompactForm( string text )
{
  if ( string.IsNullOrEmpty(text) ) throw new ArgumentException("text") ;
  if ( string.Length < 4 ) throw new ArgumentException("text") ;

  int            YYYY  = text.Length >=  4 ? int.Parse(text.Substring(  0 , 4 ) ) : 1    ;
  int            MM    = text.Length >=  6 ? int.Parse(text.Substring(  4 , 2 ) ) : 1    ;
  int            DD    = text.Length >=  8 ? int.Parse(text.Substring(  6 , 2 ) ) : 1    ;
  int            hh    = text.Length >= 10 ? int.Parse(text.Substring(  8 , 2 ) ) : 0    ;
  int            mm    = text.Length >= 12 ? int.Parse(text.Substring( 10 , 2 ) ) : 0    ;
  int            ss    = text.Length >= 14 ? int.Parse(text.Substring( 12 , 2 ) ) : 0    ;
  string         tzid  = text.Length >  14 ? text.Substring(14).Trim()            : null ;
  TimeZoneInfo   tz    = TimeZoneInfo.FindSystemTimeZoneById( tzid ) ;
  DateTimeOffset value = new DateTimeOffset( YYYY , MM , DD , hh , mm , ss , tz.BaseUtcOffset ) ;
  return value ;
}

尽管如此,我确定在处理时区/偏离UTC的时候还有一些奇怪之处,我还没有得到适当的考虑,而且必须妥善处理。

答案 1 :(得分:0)

也许尝试DateTime.TryParseExact(time, ["yyyyMMddHHmmss K", "yyyyMMddHHmmss zzz"] ...

的变体

可能无法捕获所有这些内容,但请搜索http://msdn.microsoft.com/en-us/library/8kb3ddd4%28v=vs.110%29.aspx#KSpecifier以获取更多想法。