2014-01-10 128 views
5

我想解析一个包含时间,日期和时间,或者只是一个日期的输入字符串,并且我需要知道输入字符串中包含哪些部分。解析时间,日期/时间或日期

解析的实际值是没有问题的:

var dt1 = DateTime.Parse("10:00:00", CultureInfo.CurrentCulture); 
var dt2 = DateTime.Parse("10pm", CultureInfo.CurrentCulture); 
var dt3 = DateTime.Parse("01/02/2014", CultureInfo.CurrentCulture); 
var dt4 = DateTime.Parse("01/02/2014 10:00:00", CultureInfo.CurrentCulture); 

这些都成功地解析为你所期望的。

但是,如果未提供日期元素,DateTime.Parse会自动将当前日期添加到时间。因此,如果今天是2014年1月1日,那么DateTime.Parse("10pm")实际上会返回设置为1/1/2014 10:00:00的DateTime对象。

此外,如果我解析一个没有时间元素的输入字符串,那么DateTime.Parse假定时间为00:00:00。

因此,在解析发生后,只需检查生成的DateTime对象,我无法确定原始输入字符串是指定日期和时间,还是仅指定日期或仅指定时间。

我可以使用一个简单的RegEx查找标准时间模式,例如, ^\d\d:\d\d$但我不想假定所有文化都使用相同的模式来指定时间。

我该如何可靠地检测哪些日期和时间元素在原始输入字符串中提供,而不管文化如何,以及不使用某些仅适用于某些文化的模糊正则表达式?

+0

那么,它被命名为'日期时间' – Steve

+0

我还有什么可以用来做到这一点? – BG100

+0

你如何确定你应该使用日期还是时间? – scheien

回答

5

你可以使用DateTime.ParseDateTimeStyles.NoCurrentDateDefault防止您从当前日期:

CultureInfo culture = CultureInfo.InvariantCulture; 

var dt1 = DateTime.Parse("10:00:00", culture, DateTimeStyles.NoCurrentDateDefault); 
var dt2 = DateTime.Parse("10pm", culture, DateTimeStyles.NoCurrentDateDefault); 
var dt3 = DateTime.Parse("01/02/2014", culture, DateTimeStyles.NoCurrentDateDefault); 
var dt4 = DateTime.Parse("01/02/2014 10:00:00", culture, DateTimeStyles.NoCurrentDateDefault); 
// problem, is this a date only or a date+time? 
var dt5 = DateTime.Parse("01/02/2014 00:00:00", culture, DateTimeStyles.NoCurrentDateDefault); 

现在年为1。这样你至少可以只认倍。在没有时间和午夜日期时间的情况下,您仍然有问题需要区分。

因此,这可能已经足够:

bool dt1TimeOnly, dt1DateOnly, dt1DateAndTime; 
dt1TimeOnly = dt1.Year == 1; 
dt1DateOnly = !dt1TimeOnly && dt1.TimeOfDay == TimeSpan.FromHours(0); 
dt1DateAndTime = !dt1TimeOnly && !dt1DateOnly; 

所以唯一的办法准确地识别输入是提供所有支持的格式,并使用每个DateTime.TryParseExact

例如与此枚举:

public enum DateTimeType 
{ 
    Date, 
    Time, 
    DateTime, 
    Unknown 
} 

而且这种方法:

public DateTimeType GetDateTimeType(string input, CultureInfo culture, out DateTime parsedDate) 
{ 
    if(culture == null) culture = CultureInfo.CurrentCulture; 
    var supportedFormats = new[] { 
     new{ Pattern = culture.DateTimeFormat.ShortDatePattern, Type = DateTimeType.Date }, 
     new{ Pattern = culture.DateTimeFormat.ShortTimePattern, Type = DateTimeType.Time }, 
     new{ Pattern = culture.DateTimeFormat.LongDatePattern, Type = DateTimeType.Date }, 
     new{ Pattern = culture.DateTimeFormat.LongTimePattern, Type = DateTimeType.Time }, 
     new{ Pattern = "hhtt", Type = DateTimeType.Time}, 
     new{ 
      Pattern = culture.DateTimeFormat.ShortDatePattern + " " + culture.DateTimeFormat.LongTimePattern, 
      Type = DateTimeType.DateTime 
     } 
    }; 

    foreach(var fi in supportedFormats) 
    { 
     DateTime dt; 
     if (DateTime.TryParseExact(input, fi.Pattern, culture, DateTimeStyles.NoCurrentDateDefault, out dt)) 
     { 
      parsedDate = dt; 
      return fi.Type; 
     } 
    } 
    parsedDate = default(DateTime); 
    return DateTimeType.Unknown; 
} 

现在,这产生了正确的日期和DateTimeTypes

DateTime dt1; 
DateTimeType type1 = GetDateTimeType("10:00:00", culture, out dt1); 
DateTime dt2; 
DateTimeType type2 = GetDateTimeType("10pm", culture, out dt2); 
DateTime dt3; 
DateTimeType type3 = GetDateTimeType("01/02/2014", culture, out dt3); 
DateTime dt4; 
DateTimeType type4 = GetDateTimeType("01/02/2014 10:00:00", culture, out dt4); 
DateTime dt5; 
DateTimeType type5 = GetDateTimeType("01/02/2014 00:00:00", culture, out dt5); 
+0

这是完美的...我没有发现DateTimeStyles.NoCurrentDateDefault选项,这正是我需要检测一个只有时间的输入。我想我可能能够逃脱仅限于日期的午夜部分...所以感谢您的帮助! – BG100

+0

@ BG100:请注意,我已经添加了一个关于如何解决“日期”和“时间”问题的示例。 –