Przeprosiny, jeśli wcześniej zostały zadane. Mam niektóre dane, które muszę przechowywać jako ciągi, niektóre z tych danych są datami. Dane zaczynają się od ciągów takich jak "01/02/10" (format uk). Teraz, później, te dane są analizowane i, w zależności od tego, co jest analizowane, wyniki są różne (na przykład 01-Feb-10 vs. 02-Jan-10). Biorąc pod uwagę, że dane zaczynają się jako łańcuchy, zanim je zapiszę, chciałbym powiedzieć, "jeśli to wygląda jak data, sformatuj ją jako dd-mmm-rr".Pisanie odpowiednika IsDate() w języku C#?
Problem polegający na tym, że wiele rzeczy wygląda jak data w funkcji DateTime.Parse().
Zastosowałem więc pewne reguły i akceptuję tylko "rozsądne" formaty dat dla moich kontroli i napisałem funkcję IsDate(). Szukam sugestii, jak to zrobić, ponieważ, podczas gdy działa, moje rozwiązanie wydaje się bardzo nieporęczne.
Cały powód, dla którego zrobiłem to zamiast przejść do zwykłej procedury DateTime.TryParse jest jasne, jeśli kiedykolwiek zacząłeś wyrzucać losowe ciągi znaków (jak "3/4" i "6.12").
Oto co mam do tej pory:
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;
}
}
nie używać separatorów data/czas od informacji hodowli, bo chciałem przyjąć zarówno „/” i „-”. Sądzę, że mogłem wykorzystać ten czas, ponieważ to mało prawdopodobne, aby się zmieniło (dla mnie).
Dlaczego nie korzystać z DateTime.TryParse, a następnie wykonać pewne badanie poprawności, na przykład na części roku zwrócony DateTime? –