Написание эквивалентного IsDate () в C #? - PullRequest
6 голосов
/ 15 октября 2010

Извиняюсь, если об этом спрашивали раньше.У меня есть некоторые данные, которые мне нужно хранить в виде строк, некоторые из которых являются датами.Данные начинаются в виде строк, таких как "01/02/10" (формат Великобритании) .Теперь, позже, эти данные анализируются и, в зависимости от того, что делает анализ, результаты различаются (например, 01 февраля-10 против 02 января-10).Учитывая, что данные начинаются как строки, перед тем, как их сохранить, я бы хотел сказать, "если это похоже на дату, отформатируйте ее как dd-mmm-yy" .

.проблема в том, что многие вещи похожи на дату для функции DateTime.Parse ().

Итак, я применил некоторые правила и принимаю только «разумные» форматы дат для своих проверок и написал функцию IsDate ().Я ищу предложения о том, как это сделать, потому что, хотя оно работает, мое решение кажется очень неуклюжим.

Вся причина, по которой я это сделал, а не пошла дальше по обычной процедуре DateTime.TryParse, ясна, если у вас естькогда-нибудь начал бросать в него случайные строки (например, "3/4" и "6.12").

Вот что у меня есть:

class Program
{
  static void Main(string[] args)
  {
     Debug.Assert(IsDate(6.12) == false);
     Debug.Assert(IsDate("3/4") == false);
     Debug.Assert(IsDate(010210) == false);
     Debug.Assert(IsDate("010210") == false);
     Debug.Assert(IsDate("12-jan-2000") == true);
     Debug.Assert(IsDate("12-12-20") == true);
     Debug.Assert(IsDate("1/1/34") == true);
     Debug.Assert(IsDate("09/30/20") == false);
     Debug.Assert(IsDate(DateTime.Now) == true);
  }

  static Boolean IsDate(Object value)
  {
     DateTimeFormatInfo DateTimeFormatGB = new CultureInfo("en-GB").DateTimeFormat; // new CultureInfo("en-US").DateTimeFormat;
     return IsDate(value, DateTimeFormatGB);
  }

  static private List<String> AcceptableDateFormats = new List<String>(72);
  static Boolean IsDate(Object value, DateTimeFormatInfo formatInfo)
  {
     if (AcceptableDateFormats.Count == 0)
     {
        foreach (var dateFormat in new[] { "d", "dd" })
        {
           foreach (var monthFormat in new[] { "M", "MM", "MMM" })
           {
              foreach (var yearFormat in new[] { "yy", "yyyy" })
              {
                 foreach (var separator in new[] { "-", "/" }) // formatInfo.DateSeparator ?
                 {
                    String shortDateFormat;
                    shortDateFormat = dateFormat + separator + monthFormat + separator + yearFormat;
                    AcceptableDateFormats.Add(shortDateFormat);
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH:mm"); // formatInfo.TimeSeparator
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH:mm:ss");
                 }
              }
           }
        }
     }

     String sValue = value.ToString().Trim();
     DateTime unused;

     foreach (String format in AcceptableDateFormats)
     {
        if (DateTime.TryParseExact(sValue, format, formatInfo, DateTimeStyles.None, out unused) == true) return true;
     }

     return false;
  }
}

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

Ответы [ 9 ]

7 голосов
/ 15 октября 2010

Вы проверяли DateTime.TryParse () альтернативное переопределение, когда оно дает вам гораздо больший контроль над тем, что он считает датой?

6 голосов
/ 15 октября 2010

Преобразование строки в дату. Вы можете указать культуру, которая использует этот конкретный формат: например, мы хотим преобразовать строковую дату «дд / мм / гггг» в дату ..

datetime mydate = Convert.ToDateTime(
txtdate.Text, CultureInfo.GetCulture("en-GB")
);

или использовать ParseExactМетод:

datetime mydate = DateTime.ParseExact(
txtdate.Text, "dd/MM/yyyy", CultureInfo.Invariant
);

Метод ParseExact принимает только этот определенный формат, в то время как метод Convert.ToDateTime по-прежнему допускает некоторые вариации формата, а также принимает некоторые другие форматы даты.

Для перехватаНеверный ввод, вы можете использовать метод TryParseExact:

DateTime d;
if (DateTime.TryParseExact(txtdate.Text, "dd/MM/yyyy", CultureInfo.Invariant, DateTimeStyles.None, out d)) {
datetime mydate = d;
} else {
// communcate the failure to the user
} 

Надеюсь, что ссылки ниже помогут вам:

http://dotnetacademy.blogspot.com/2010/09/convert-string-to-date.html

http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx

http://msdn.microsoft.com/en-us/library/9h21f14e.aspx

http://dotnetacademy.blogspot.com/2009/10/get-current-system-date-format.html

Это пример для tryParse: http://dotnetperls.com/datetime-tryparse

6 голосов
/ 15 октября 2010

Рассмотрите возможность использования DateTime.TryParseExact

1 голос
/ 31 мая 2013

Это, очевидно, хак, но в итоге я добавил Справочник по VisualBasic и просто использовал функцию IsDate в C #:

using Microsoft.VisualBasic;
//...other code...
if (Information.IsDate(YourDateObject)) {
   //...more code...
}
1 голос
/ 05 апреля 2011

в конце концов я пошел с версией следующего:

  static private List<String> AcceptableDateFormats = new List<String>(180);
  static Boolean IsDate(Object value, DateTimeFormatInfo formatInfo)
  {
     if (AcceptableDateFormats.Count == 0)
     {
        foreach (var dateFormat in new[] { "d", "dd" })
        {
           foreach (var monthFormat in new[] { "M", "MM", "MMM" })
           {
              foreach (var yearFormat in new[] { "yy", "yyyy" })
              {
                 foreach (var separator in new[] { "-", "/", formatInfo.DateSeparator  })
                 {
                    String shortDateFormat;
                    shortDateFormat = dateFormat + separator + monthFormat + separator + yearFormat;
                    AcceptableDateFormats.Add(shortDateFormat);
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH:mm");
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH:mm:ss");
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH" + formatInfo.TimeSeparator + "mm");
                    AcceptableDateFormats.Add(shortDateFormat + " " + "HH" + formatInfo.TimeSeparator + "mm" + formatInfo.TimeSeparator + "ss");
                 }
              }
           }
        }
        AcceptableDateFormats = AcceptableDateFormats.Distinct().ToList();
     }

     DateTime unused;
     return DateTime.TryParseExact(value.ToString(), AcceptableDateFormats.ToArray(), formatInfo, DateTimeStyles.AllowWhiteSpaces, out unused);
  }
1 голос
/ 15 октября 2010

Попробуйте

DateTime result;
DateTime.TryParseExact(value.ToString(), new string[] { "dd/MM/yyyy", "d/M/yyyy" }, null, DateTimeStyles.None, out result)
1 голос
/ 15 октября 2010

Вы проверили попытку перегрузки DateTime.TryParse, которая принимает аргументы IFormatProvider и DateTimeStyles? Вы можете использовать это, чтобы быть более разборчивым в отношении того, что вы принимаете в качестве фактической даты, при этом не создавая ненужных исключений только для проверки строк.

0 голосов
/ 15 октября 2010
using System.Globalization;

CultureInfo ukCI = CultureInfo.CreateSpecificCulture("en-GB");
Console.WriteLine(DateTime.Parse("1/2/2010", ukCI).ToString("dd-MMM-yyyy"));

Вы можете использовать TryParse вместо Parse, если хотите подтвердить, что аргумент является датой.

0 голосов
/ 15 октября 2010

В качестве альтернативы вы можете иметь свою собственную проверку регулярного выражения после того, как найдете потенциальную дату, если вам требуется более высокий уровень контроля. как то так.

^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$

охватывает xx-yy-zz и xx / yy / zz согласно вашему требованию

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