Почему бы не сохранить в конфигурации регулярное выражение и соответствующую строку формата для DateTime.ParseExact?
Конечно, вам придется приложить некоторые усилия для определения правильных значений, но тогда это всего лишь вопрособновление конфига и все готово.
У вас все еще будет проблема с анализом даты, если вы не укажете ей формат или он соответствует стандартному формату.
Редактировать:Я надеюсь, что вы не возражаете против того, чтобы я как-то угадал вопрос, но мне было любопытно обсудить Regex, TryParseExact и Exception, поэтому я провел небольшой тест.Приведенный ниже код анализирует одно и то же имя файла 100 000 раз, чтобы определить и преобразовать внедренную дату.
Я удостоверился, что код запускается в режиме выпуска и без подключенного отладчика;обработка исключений при отладке в Visual Studio является убийцей.
Я обнаружил, что методы Regex и TryParseExact были очень близки.Неудивительно, что с увеличением количества уровней в пути метод Regex стал немного более эффективным, но в нем все еще ничего нет.Если путь вообще не содержит дату, баланс немного смещается в сторону метода Regex, но этого недостаточно, чтобы внести существенную разницу.
Использование «неправильного» способа полагаться на обработку исключений былоно все же несколько иначе!
Мое время для кода, показанного ниже, было:
Using Regex:
Duration: 543.0543
Using TryParse:
Duration: 429.0429
Using Exceptions:
Duration: 11930.4865
Это время в миллисекундах.Первоначально я выполнял 1 миллион итераций, но мне было скучно, когда я выполнял «Исключения»; -)
Эксперимент показывает, что методы Regex и TryParseExact довольно сопоставимы по производительности, но метод TryParseExact имеет существенное значениеПреимущество в том, что ему не нужно определять или получать регулярное выражение.Без сомнения, это хороший выбор для этой проблемы.
Это также иллюстрирует накладные расходы на обработку исключения.Это не удивительно, так как процесс разматывания стека потенциально сложен и требует много времени.Приложение потратило 95% своего времени на обработку исключений.Это хорошо иллюстрирует аргумент, что вы не должны полагаться на обработку исключений для разбора даты - отсюда и существование методов TryParse ....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
static Regex r = new Regex(@"\d{4}_[a-zA-Z]{3}_\d{1,2}");
static string dateFormat = "yyyy_MMM_d";
static CultureInfo provider = CultureInfo.InvariantCulture;
static void Main(string[] args)
{
string filepath = @"C:\TopDir\SubDir\2011_JUL_26\filename.ext";
DateTime startTime;
DateTime endTime;
TimeSpan duration;
bool success;
DateTime result;
System.Console.WriteLine("Using Regex:");
startTime = DateTime.Now;
for (int ix = 0; ix < 100000; ix++)
{
success = UsingRegex(filepath, out result);
}
endTime = DateTime.Now;
duration = endTime - startTime;
System.Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString());
System.Console.WriteLine("Using TryParse:");
startTime = DateTime.Now;
for (int ix = 0; ix < 100000; ix++)
{
success = UsingTryParse(filepath, out result);
}
endTime = DateTime.Now;
duration = endTime - startTime;
System.Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString());
System.Console.WriteLine("Using Exceptions:");
startTime = DateTime.Now;
for (int ix = 0; ix < 100000; ix++)
{
success = UsingExceptions(filepath, out result);
}
endTime = DateTime.Now;
duration = endTime - startTime;
System.Console.WriteLine("Duration: " + duration.TotalMilliseconds.ToString());
}
static bool UsingRegex(string filepath, out DateTime result)
{
var matches = r.Matches(filepath);
if (matches.Count > 0)
{
return DateTime.TryParseExact(matches[0].Value, dateFormat,
provider, DateTimeStyles.None, out result);
}
result = DateTime.MinValue;
return false;
}
static bool UsingTryParse(string filepath, out DateTime result)
{
var parts = filepath.Split('\\');
foreach (var part in parts)
{
if( DateTime.TryParseExact(part, dateFormat, provider,
DateTimeStyles.None, out result) )
{
return true;
}
}
result = DateTime.MinValue;
return false;
}
static bool UsingExceptions(string filepath, out DateTime result)
{
var parts = filepath.Split('\\');
foreach (var part in parts)
{
try
{
result = DateTime.ParseExact(part, dateFormat,
provider, DateTimeStyles.None);
return true;
}
catch(Exception ex)
{
}
}
result = DateTime.MinValue;
return false;
}
}
}