Verifica se una stringa è una data valida utilizzando DateTime.TryParse

Sto usando la funzione DateTime.TryParse() per controllare se una determinata stringa è un datetime valido non dipendente da alcuna cultura.
Con mia sorpresa, la funzione restituisce true per stringhe pari a “1-1”, “1/1” .etc.

Come posso risolvere questo problema?

Aggiornare:

Significa, se voglio controllare se una determinata stringa è valida datetime, ho bisogno di una vasta gamma di formati ?? Ci saranno diverse combinazioni, credo.
Anche se ci sono molti separatori di date (‘.’, ‘/’, ‘-‘, ecc.) A seconda della cultura, sarà difficile per me definire una serie di formati da controllare.
Fondamentalmente, voglio verificare se una stringa particolare contiene ALMENO giorno (da 1 a 31 o da 01 a 31), mese (da 1 a 12 o da 01 a 12) e anno (aaaa o aa) in qualsiasi ordine, con qualsiasi separatore di data, quale sarà la soluzione?
Quindi, se il valore include parti di tempo, dovrebbe restituire anche true. Non potrei essere in grado di definire una matrice di formato.

Se si desidera che le date siano conformi a un formato o formati particolari, utilizzare DateTime.TryParseExact altrimenti si tratta del comportamento predefinito di DateTime.TryParse

DateTime.TryParse

Questo metodo tenta di ignorare i dati non riconosciuti , se ansible, e inserisce le informazioni mancanti di mese, giorno e anno con la data corrente. Se s contiene solo una data e nessuna ora, questo metodo presuppone che l’ora sia mezzanotte 12:00. Se s include un componente data con un anno a due cifre, viene convertito in un anno nel calendario corrente della cultura corrente in base al valore della proprietà Calendar.TwoDigitYearMax. Qualsiasi carattere iniziale, interno o finale di spazio bianco in s viene ignorato.

Se si desidera confermare su più formati, esaminare l’overload DateTime.TryParseExact Method (String, String [], IFormatProvider, DateTimeStyles, DateTime) . Esempio dallo stesso link:

 string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", "M/d/yyyy h:mm", "M/d/yyyy h:mm", "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"}; string[] dateStrings = {"5/1/2009 6:32 PM", "05/01/2009 6:32:05 PM", "5/1/2009 6:32:00", "05/01/2009 06:32", "05/01/2009 06:32:00 PM", "05/01/2009 06:32:00"}; DateTime dateValue; foreach (string dateString in dateStrings) { if (DateTime.TryParseExact(dateString, formats, new CultureInfo("en-US"), DateTimeStyles.None, out dateValue)) Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue); else Console.WriteLine("Unable to convert '{0}' to a date.", dateString); } // The example displays the following output: // Converted '5/1/2009 6:32 PM' to 5/1/2009 6:32:00 PM. // Converted '05/01/2009 6:32:05 PM' to 5/1/2009 6:32:05 PM. // Converted '5/1/2009 6:32:00' to 5/1/2009 6:32:00 AM. // Converted '05/01/2009 06:32' to 5/1/2009 6:32:00 AM. // Converted '05/01/2009 06:32:00 PM' to 5/1/2009 6:32:00 PM. // Converted '05/01/2009 06:32:00' to 5/1/2009 6:32:00 AM. 

Utilizzare DateTime.TryParseExact() se si desidera confrontare uno specifico formato di data

  string format = "ddd dd MMM h:mm tt yyyy"; DateTime dateTime; if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime)) { Console.WriteLine(dateTime); } else { Console.WriteLine("Not a date"); } 
 [TestCase("11/08/1995", Result= true)] [TestCase("1-1", Result = false)] [TestCase("1/1", Result = false)] public bool IsValidDateTimeTest(string dateTime) { string[] formats = { "MM/dd/yyyy" }; DateTime parsedDateTime; return DateTime.TryParseExact(dateTime, formats, new CultureInfo("en-US"), DateTimeStyles.None, out parsedDateTime); } 

Basta specificare i formati di data e ora che si desidera accettare nell’array con i formati .

Ho risolto il problema con il seguente codice:

 protected bool CheckDate(String date) { try { DateTime dt = DateTime.Parse(date); return true; } catch { return false; } } 

Fondamentalmente, voglio verificare se una stringa particolare contiene ALMENO giorno (da 1 a 31 o da 01 a 31), mese (da 1 a 12 o da 01 a 12) e anno (aaaa o aa) in qualsiasi ordine, con qualsiasi separatore di data, quale sarà la soluzione? Quindi, se il valore include parti di tempo, dovrebbe restituire anche true. Non potrei essere in grado di definire una matrice di formato.

Quando ero in una situazione simile, ecco cosa ho fatto:

  1. Raccogli tutti i formati che il mio sistema dovrebbe supportare.
  2. Osservato ciò che è comune o può essere generalizzato.
  3. Imparato a creare REGEX (è un investimento di tempo inizialmente ma ripaga una volta creati uno o due da soli). Inoltre, non provare a creare REGEX per tutti i formati in una sola volta, seguire la procedura incrementale.
  4. Ho creato REGEX per coprire il maggior numero ansible di formati.
  5. In alcuni casi, per non rendere REGEX più complesso, l’ho coperto tramite il metodo DateTime.Parse ().
  6. Con la combinazione di Parse e REGEX ho potuto validare l’input corretto / come previsto.

Questo http://www.codeproject.com/Articles/13255/Validation-with-Regular-Expressions-Made-Simple è stato molto utile sia per la comprensione sia per la convalida della syntax per ogni formato.

I miei 2 centesimi se aiuta ….

Prova a usare

 DateTime.ParseExact( txtPaymentSummaryBeginDate.Text.Trim(), "MM/dd/yyyy", System.Globalization.CultureInfo.InvariantCulture ); 

Genera un’eccezione se la stringa di input non è nel formato corretto, quindi nella sezione catch è ansible return false;

Quindi questa domanda ha avuto risposta, ma per me il codice utilizzato non è abbastanza semplice o completo. Per me questo pezzo qui è quello che stavo cercando e forse anche ad altre persone piacerà.

 if (DateTime.TryParse(DateString, out DateTime Temp) == true) { //do stuff }