Надежная библиотека парсера DateTime для .NET

Я пишу приложение для чтения RSS и почты на С# (технически MonoTouch).

Я столкнулся с проблемой разбора DateTimes. Я вижу много различий в том, как даты представлены в дикой природе, и начал писать такую ​​​​функцию:

static string[] DateTimeFormats = new string[] {
    "ddd, d MMM yyyy H:mm:ss \"GMT+00:00\"",
    "d MMM yyyy H:mm:ss \"EST\"",
    "yyyy-MM-dd\"T\"HH:mm:ss\"Z\"",
    "ddd MMM d HH:mm:ss \"+0000\" yyyy",
};
public static DateTime ParseTime(string timeStr) {

    var r = DateTime.MinValue;

    var styles = DateTimeStyles.AdjustToUniversal | 
                 DateTimeStyles.AllowWhiteSpaces;

    if (DateTime.TryParse(timeStr, 
                          CultureInfo.InvariantCulture,
                              styles,
                              out r)) {
        return r;
    }
    else {              
        if (DateTime.TryParseExact(timeStr, 
                                   DateTimeFormats, 
                                   CultureInfo.InvariantCulture,
                                   styles,
                                   out r)) {
            return r; // BUGGY! Ignores time zone!!
        }
    }

    Console.WriteLine ("BAAAAAAAAAAAAD");
    return DateTime.MinValue;
}

Меня тошнит от этого. Два очка. (1) Глупо с моей стороны думать, что я действительно могу собрать список форматов, который будет охватывать все, что есть. (2) Это неправильно! Обратите внимание, что я рассматриваю время даты EST как время UTC (поскольку .NET, похоже, не обращает внимания на часовые пояса).

Я ищу существующую библиотеку (только источник), которая, как известно, обрабатывает кучу этих форматов.

Кроме того, я хотел бы продолжать использовать UTC DateTimes во всем своем коде, поэтому любая предлагаемая библиотека должна иметь возможность создавать DateTimes.

Есть ли что-нибудь подобное этому?

Обновление Кажется, я не совсем ясно выразился в своем запросе. Я ищу библиотеку, которая знает много этих диких строк формата. DateTime.Parse/DateTime.TryParse знает только пару форматов, и они, конечно, не понимают часовые пояса (вы можете видеть, что я уже использую его). Мне нужно что-то более мощное, чем DateTime.Parse/DateTime.TryParse.

Обновление 2 Все обращали внимание на тот факт, что я использую Parse вместо TryParse. Я поменял код. Но это все еще неправильно и неполно.


person Frank Krueger    schedule 31.03.2010    source источник
comment
Со временем noda-time может предоставить некоторые из этих функций: code.google.com/p/noda- время   -  person TrueWill    schedule 31.03.2010


Ответы (6)


В дополнение к TryParse для DateTime, .Net также предоставляет структуру DateTimeOffset, которая предлагает доступ к смещению UTC в качестве еще одного свойства структуры, позволяя вам хранить информацию о часовом поясе и информацию о дате и времени вместе.

person Joel    schedule 31.03.2010
comment
Я просто пытаюсь избежать создания базы данных форматов самостоятельно. Наверняка кто-то уже проделал эту работу? Но спасибо за информацию, если мне придется написать ее самостоятельно, это будет полезно. - person Frank Krueger; 31.03.2010

Вы пробовали просто использовать DateTime.TryParse? Эта функция уже работает с большинством форматов.

person David    schedule 31.03.2010
comment
Я звоню в Parse (проверьте код). Такая же разница с точки зрения поддерживаемого. Каждая из предоставленных строк формата терпит неудачу DateTime.Parse. Мне нужно что-то с большим знанием. - person Frank Krueger; 31.03.2010

Вы можете использовать:

DateTime.TryParse()

вместо

DateTime.Parse()

а не попробовать/поймать

person hunter    schedule 31.03.2010
comment
Я уже делаю это (см. код). Но Parse по-прежнему не подходит для более экзотических форматов. Я могу жить с исключениями, я хочу большего разнообразия форматов. - person Frank Krueger; 31.03.2010
comment
Действительно? Я предлагаю вам сделать TryParse и TryParseExact, а не ваш try/catch. - person hunter; 31.03.2010
comment
Парс против TryParse. Они одинаковые! Один выдает исключение, другой нет. То же самое для ParseExact и TryParseExact. Они используют базу данных одного формата. Так что да, это помогает моему пункту № 3, но исключения не являются моей настоящей заботой. Мне нужен парсер, который знает много форматов. - person Frank Krueger; 31.03.2010

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

C#: анализ DateTime с помощью TimeZone
http://hashfactor.wordpress.com/2009/02/02/c-parsing-datetime-with-timezone/

В настоящее время я использую этот код из предыдущего URL-адреса в проекте. Несмотря на то, что проект еще не запущен, код работает.

БарДев

person Mike Barlow - BarDev    schedule 01.04.2010

Фрэнк, для разбора часовых поясов нужно использовать zz или zzz.

Будущие версии MonoTouch также будут поддерживать новый модификатор «K» (псевдоним для zzz).

person miguel.de.icaza    schedule 05.04.2010

Я разработал библиотеку (NaturalDate) для синтаксического анализа дат, но это может быть не то, что вы ищете, поскольку она предназначена для форм ввода человеком, а не для форм, созданных компьютером. IIRC может даже не анализировать формы, которые вы показали выше. Кроме того, сайт временно не работает (он был единственным на этом сервере).

Если у меня будет время (скорее всего, мне даже за это заплатят), я попытаюсь воскресить его как активно поддерживаемый проект.

person BCS    schedule 31.03.2010