Разбор отметки времени с начала строки в C # - PullRequest
0 голосов
/ 16 ноября 2009

Я работаю над переписыванием существующего программного решения Java в .NET.В какой-то момент решение Java читает метку времени в начале строки, просто так:

SimpleDateFormat dateFormat = new SimpleDateFormat(timeFormat);
dateFormat.setLenient(false);

try
{
    timeStamp = dateFormat.parse(line);
}
catch (ParseException e)
{
    //...
}

Теперь я пытаюсь сделать то же самое в C #:

DateTimeFormatInfo dateTimeFormatInfo = new DateTimeFormatInfo();
dateTimeFormatInfo.FullDateTimePattern = format;

try
{
    timeStamp = DateTime.Parse(line, dateTimeFormatInfo);
}
catch (FormatException ex)
{
    //...
}

Оба языка работают, пока я не добавлю некоторый случайный текст после отметки времени в переменной строки.Java просто проигнорирует это, но C # не допустит ничего другого после текста отметки времени в строке.

Так что пока Java с удовольствием разбирает "01/01/01 01: 01: 01,001 Hello World!"как отметка времени, C # нет, потому что "Hello World!"не указывается в строке формата.

Однако, поскольку я не могу утверждать, что может появиться после отметки времени внутри моих строк, я не могу включить ее в строку формата.

Любойидеи?

Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 16 ноября 2009

Попробуйте это:

Dictionary<string, string> tests = new Dictionary<string,string>()
{
    { "yy/MM/dd HH:mm:ss,fff", "01/01/01 01:01:01,001 Hello World!"},
    { "yyyyMMddHHmmssfff", "2009111615413829403 Hello World!"},
    { "d.M.yyyy H:m:s,fff", "8.10.2009 8:17:26,338 Hello World!" }
};

foreach(KeyValuePair<string, string> test in tests)
{
    string pattern = test.Key;
    string format = test.Value;

    DateTimeFormatInfo dateTimeFormatInfo = new DateTimeFormatInfo();
    dateTimeFormatInfo.FullDateTimePattern = pattern;

    Console.WriteLine("{0} - {1}", pattern, format);
    DateTime timeStamp = DateTime.MinValue;
    if (pattern.Contains(' ')) // approach 1: split and conquer
    {
        format = String.Join(" ", format
            .Split(" ".ToCharArray())
            .Take(pattern.Count(c => c == ' ') + 1));
    }
    else
    {
        format = format.Substring(0, pattern.Length);
    }


    if (!DateTime.TryParseExact(
        format, pattern, dateTimeFormatInfo, 
        DateTimeStyles.AllowWhiteSpaces, out timeStamp))
    {
        Console.WriteLine("\tSomething sad happened");
    }
    else
    {
        Console.WriteLine("\t{0}", timeStamp.ToString(pattern));
    }
}
Console.Read();

Примечание. Я не использую DateTime.Parse, поскольку он генерирует исключение, если строка не является допустимой DateTime отформатированной строкой.

ОБНОВЛЕНИЕ 1 : Лучшая обработка ввода, поскольку не ожидайте пробелов, но использует длину шаблона

ОБНОВЛЕНИЕ 2 : Два предыдущих подхода объединены в этот код; Я знаю об использовании одного d в тесте № 2, но я не думаю, что мы можем что-то с этим поделать.

1 голос
/ 16 ноября 2009

Если вы знаете, в каком формате будет ваша дата, и в каком контексте она хранится, то это преимущество.

Например, если вы знали, что хранили вчерашние логи или что-то в этом роде:

DateTime yesterday = DateTime.Today.AddDays(-1);
timestamp = DateTime.Parse(
    line.SubString(0, line.IndexOf(yesterday.Year.ToString()) + 4));

edit: Есть ли что-нибудь, разделяющее текст после даты (даже пробел)?

Если есть, вы можете сделать что-то вроде этого:

private static DateTime GetDate(string line)
{
    int index = 0;
    DateTime theDate;
    string s = line;

    while(!DateTime.TryParse(s, out theDate))
    {
        index = line.IndexOf(" ", index);
        s = line.Substring(0, index);
    }

    return theDate;
}

Примечание. При этом не будет получено время, если после даты будет текст (поскольку при поиске он сможет без разбора разобрать дату). Вы можете исправить это, получив индекс пробелов, начинающийся в конце строки и движущийся назад. Я оставлю это тебе.

0 голосов
/ 16 ноября 2009

Похоже, что .Net собирается проанализировать всю строку, а вы не контролируете всю строку. Я бы сказал, используйте TryParse (), и если это не удастся, удалите самое правое «слово» из вашей строки и повторите попытку. Я не знаком с Java, но он может сделать это под прикрытием.

...