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

本文关键字:日期 时间 格式 未知 | 更新日期: 2023-09-27 18:01:36

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

根据DTD文件:

这个DTD中的所有日期和时间都遵循相同的格式,基于松散ISO 8601。它们可以是'YYYYMMDDhhmmss'或一些初始子字符串,例如,如果您只知道年份和月份,则可以使用'YYYYMM'。您还可以在末尾附加一个时区;如果没有显式的时区给定时,假设UTC。例如:'200007281733 BST', '200209',"19880523083000 + 0300"。(BST == +0100.)

这是具有挑战性的情况,我最初想到使用DateTimeFormatInfo。gettalldatetimepatterns和使用DateTime。TryParseExact,关于时区的最后一行和带有任何分隔符的特定格式使得无法使用上述方法。

是否有一种简洁的方法来解析上述日期时间规范,或者是否只需要不断寻找/添加各种模式来解析字符串,因为发现它们(看起来几乎无穷无尽的组合)

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

嗯,您可能会这样做,使用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的偏移量方面有一些奇怪的地方,我没有适当地考虑过,必须适当地处理。

可以试试DateTime.TryParseExact(time, ["yyyyMMddHHmmss K", "yyyyMMddHHmmss zzz"] ...的变体

可能不能抓住所有的,但搜索http://msdn.microsoft.com/en-us/library/8kb3ddd4%28v=vs.110%29.aspx#KSpecifier可以获得更多的想法。