2009-11-19 5 views
20

Результат следующего фрагмента: «12.06.1930 12:00:00». Как я могу контролировать предполагаемый век, чтобы вместо этого «12 июня 30» стал 2030?DateTime.TryParse century control C#

string dateString = "12 Jun 30"; //from user input 
    DateTime result; 
    DateTime.TryParse(dateString, new System.Globalization.CultureInfo("en-GB"),System.Globalization.DateTimeStyles.None,out result); 
    Console.WriteLine(result.ToString()); 

Пожалуйста, отложите, на данный момент, тот факт, что правильно решение правильно указать дату, в первую очередь.

Примечание: результат не зависит от системного времени и времени для компьютера, на котором запущен код.

Ответ: Спасибо Deeksy

for (int i = 0; i <= 9; i++) 
    { 
     string dateString = "12 Jun " + ((int)i * 10).ToString(); 
     Console.WriteLine("Parsing " + dateString); 
     DateTime result; 
     System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-GB"); 
     cultureInfo.Calendar.TwoDigitYearMax = 2099; 
     DateTime.TryParse(dateString, cultureInfo , System.Globalization.DateTimeStyles.None, out result); 
     Console.WriteLine(result.ToString()); 
    } 
+0

Другое преимущество этого подхода заключается в том, что некоторое время в базе данных вершин на 2067, поэтому установив TwoDigitYearMax в 2067 работает хорошо. – Nat

ответ

18

Это сложно, потому как две цифры года работы с TryParse основан на свойстве TwoDigitYearMax в календарном свойства объекта CultureInfo, который вы используете. (CultureInfo-> Calendar-> TwoDigitYearMax)

Для того, чтобы сделать двухзначные годы с 20 добавочными, вам нужно вручную создать объект CultureInfo, у которого есть объект Calendar с 2099, установленным как свойство TwoDigitYearMax. К сожалению, это означает, что любая двузначная дата синтаксиса будет содержать 20 добавочных (включая 98, 99 и т. Д.), Что, вероятно, не то, что вы хотите.

Я подозреваю, что ваш лучший вариант - использовать стороннюю парсинг-версию даты вместо стандартного tryparse, который будет использовать правило + 50/-50 год для двухзначных лет. (что двузначный год должен быть переведен в диапазон от 50 лет до этого года и на 50 лет больше, чем в этом году).

В качестве альтернативы вы можете переопределить метод ToFourDigitYear объекта календаря (он является виртуальным) и использовать его для реализации правила -50/+ 50.

+0

Noda time ftw! http://noda-time.blogspot.com/ – RCIX

+0

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

+2

Хотя ответ довольно старый, я задаюсь вопросом о необходимости использования сторонних библиотек для правила +/- 50. Если требуется правило +/- 50, почему бы не просто установить 'TwoDigitYearMax' на' DateTime.Today.Год + 50'? – grek40

8

Я бы написать многоразовое функцию:

public static object ConvertCustomDate(string input) 
{ 
    //Create a new culture based on our current one but override the two 
    //digit year max. 
    CultureInfo ci = new CultureInfo(CultureInfo.CurrentCulture.LCID); 
    ci.Calendar.TwoDigitYearMax = 2099; 
    //Parse the date using our custom culture. 
    DateTime dt = DateTime.ParseExact(input, "MMM-yy", ci); 
    return new { Month=dt.ToString("MMMM"), Year=dt.ToString("yyyy") }; 
} 

Вот мой список квази-строки с датой

List<string> dates = new List<string>(new []{ 
    "May-10", 
    "Jun-30", 
    "Jul-10", 
    "Apr-08", 
    "Mar-07" 
}); 

Scan над ним, как так:

foreach(object obj in dates.Select(d => ConvertCustomDate(d))) 
{ 
    Console.WriteLine(obj); 
} 

Notice что он обрабатывает 30 как 2030 теперь вместо 1930 ...

-1
result = year.ToString().Length == 1 
     || year.ToString().Length == 2 ? "1" 
     : (Convert.ToInt32(year.ToString() 
      .Substring(0, (year.ToString().Length - 2))) + 1).ToString(); 
+0

Это поздний ответ на вопрос с уже установленным ответом. В будущем, пожалуйста, постарайтесь быть более осторожными с форматированием и предоставить больше информации о том, почему этот ответ лучше, чем широко принятый ответ. – Claies

1

У меня была аналогичная проблема, и я решил ее с помощью регулярного выражения. В вашем случае это будет выглядеть так:

private static readonly Regex DateRegex = new Regex(
@"^[0-9][0-9] (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9][0-9]$", 
RegexOptions.Compiled | RegexOptions.ExplicitCapture); 

private static string Beautify(string date) 
{ 
    var match = DateRegex.Match(date); 
    if (match.Success) 
    { 
     // Maybe further checks for correct day 
     return date.Insert("dd-MMM-".Length, "20"); 
    } 

    return date; 
} 
+0

Наибольший недостаток заключается в том, что синтаксический анализ даты статичен, учитывая, что цель состоит в том, чтобы читать данные пользователя, более гибкий подход к синтаксическому анализу даты полезен. – Nat

Смежные вопросы