DateTime.TryParse века управления C # - PullRequest
20 голосов
/ 19 ноября 2009

Результат следующего фрагмента: "12/06/1930 12:00:00". Как мне контролировать подразумеваемый век, чтобы вместо «12 июня 30» наступил 2030 год?

    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());

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

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

Ответ: Спасибо, Дикси

    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());
    }

Ответы [ 5 ]

21 голосов
/ 19 ноября 2009

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

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

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

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

11 голосов
/ 18 августа 2010

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

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"
});

Сканируйте его так:

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

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

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

Вы ищете Calendar.TwoDigitYearMax Свойство .

Джон Скит опубликовал что-то, что вы, вероятно, найдете полезным.

1 голос
/ 11 февраля 2018

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

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 голосов
/ 11 февраля 2015
result = year.ToString().Length == 1 
      || year.ToString().Length == 2 ? "1" 
       : (Convert.ToInt32(year.ToString()
          .Substring(0, (year.ToString().Length - 2))) + 1).ToString();
...