Разделить строки DateTime при преобразовании - PullRequest
3 голосов
/ 10 октября 2010

Я пишу класс C #, который будет конвертировать строки в даты.Довольно легко, я думаю.Класс принимает строки форматов, такие как "yyyy-MM-dd" и строки ввода, такие как "2010-10-10"

Однако у меня есть несколько случаев, которые вызывают у меня проблемы:

format "yyyyMMdd" input "19950000"

или

format "dd-MM-yyyy" input "00-06-2001"

Обратите внимание, что в этих случаях есть нули ('00') для дня и / или месяца, и что они не могут быть преобразованы в DateTime.Мне нужно заменить их.

Для обработки этих случаев мне нужно разбить входную строку на части, по одной на день, месяц и год, чтобы я мог установить некоторые день и месяц по умолчанию (вероятно, 01) если они отсутствуют.Но мне нужно использовать formattring для этого.

Итак, вопрос в том, как разделить строку ввода на компоненты, указанные в строке format? *

Спасибо

[ОБНОВЛЕНИЕ] Используя ответ Джо, я пришел к следующему:

string[] formats = { format, format.Replace("dd", "00").Replace("MM", "00"), format.Replace("dd", "00"), format.Replace("MM", "00") };

// Parse input
DateTime d = DateTime.ParseExact(txtDate.Text, formats, CultureInfo.InvariantCulture, DateTimeStyles.None);

При этом используется предоставленный формат и создаются альтернативные форматы с нулями ('00') для дня, месяца и дня и месяца.

Спасибо, Джо!

Ответы [ 3 ]

3 голосов
/ 10 октября 2010

Если у вас есть четко определенный набор форматов, вы можете использовать DateTime.ParseExact, передавая массив строк формата.

// Define all allowed formats
string[] formats =  { "yyyyMMdd", "yyyyMM00", "yyyy0000" };

// Parse input
DateTime d;
d = DateTime.ParseExact("20100930", formats, 
                 CultureInfo.InvariantCulture, DateTimeStyles.None);
d = DateTime.ParseExact("20100900", formats, 
                 CultureInfo.InvariantCulture, DateTimeStyles.None);
d = DateTime.ParseExact("20100000", formats, 
                 CultureInfo.InvariantCulture, DateTimeStyles.None);

Недостающие дни / месяцы будут установлены по умолчанию в 1.

3 голосов
/ 10 октября 2010

Мой подход заключается в определении различных регулярных выражений и использовании шаблона проектирования цепочки ответственности, передавая значение первому, если совпадение останавливается на этом, и если не отправляется следующему, пока одно из них не совпадет со строкой.

Мой шаблон регулярного выражения будет разделять элемент даты, месяца и года и устанавливать для каждого из них значение по умолчанию, если оно равно 0.

Здесь для Chain-of-ответственность_pattern: http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

private const string Pattern_dd-mm-yyyy = "(\d\d)-(\d\d)-(\d){4}";
private const string Pattern_ddmmyyyy = "(\d\d)(\d\d)(\d){4}";
private const string Pattern_ddSlashmmSlashyyyy = "(\d\d)/(\d\d)/(\d){4}";
1 голос
/ 10 октября 2010

Я не совсем понимаю вашу проблему (у меня нет представителя для комментариев), но я все еще могу дать вам несколько советов.

Прежде всего, класс DateTime предоставляет метод ParseExact (http://msdn.microsoft.com/en-us/library/w2sa9yss(v=VS.80).aspx), который принимает строку форматирования для даты и времени. Вы можете передать ей строку формата

Я не совсем понимаю часть о случаях: вам нужно принимать метки времени в нескольких форматах? Если это так, вы можете попробовать / перехватить, пока не найдете совпадение, или выполнить цикл, используя метод TryParseExact, который почти работает так же.

Получив значение DateTime, используйте свойства Year, Month и Day, чтобы получить компоненты, которые вы искали во входной строке

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...