Wartości dziesiętne rozpoznawane jako DateTime zamiast zwracać false z DateTime.Parse

9

Muszę wykonać sprawdzenie na podstawie wartości ciągu, niezależnie od tego, czy jest to data, czy liczba dziesiętna, ale parsowanie daty zawsze zwraca wartość prawda po przecinku.

string val = "3.5";
DateTime oDate = DateTime.Parse(val);

Zwraca prawidłową datę 3/5/2019.

Jak zweryfikować ciąg, aby poznać jego prawidłową datę, gdy format daty nie jest znany?

Munawar
źródło
6
Sprawdź najpierw dziesiętny? Lub użyj, DateTime.ParseExactjeśli wiesz, jakie formaty może / powinien przyjąć
Przyjaciel
3
Możesz użyć TryParseExacti określić prawidłowe formaty daty.
juharr
5
Rzeczywiście - DateTime.Parsepróbuje wielu wzorów. Jeśli chcesz rozpoznać tylko określone, spróbuj je dokładnie przeanalizować.
Jon Skeet,

Odpowiedzi:

3

„Jak sprawdzić poprawność ciągu, aby poznać jego prawidłową datę?”

Problem polega na tym, że "3.5" jest uważana za prawidłową datę (a także dziesiętną).

Jeśli chcesz, aby typ dziesiętny zawsze „wygrywał” (tzn. Nie chcesz isDatei isDecimaloba mają być true), włącz sprawdzanie dziesiętne w walidacji.

Jednym ze sposobów na to jest użycie TryParsemetod (które zwracają a, booljeśli ciąg może zostać przeanalizowany z typem i który ustawia outparametr na przekonwertowaną wartość), aby ustalić, czy ciąg może zostać przekonwertowany na typ, na przykład:

string val = "3.5";

// temp variables to hold parsed values
DateTime tmpDate;
decimal tmpDec;
int tmpInt;

var isDecimal = decimal.TryParse(val, out tmpDec);
var isInteger = int.TryParse(val, out tmpInt);

// When checking if it's a DateTime, make sure it's not also a decimal
var isDate = !isDecimal && DateTime.TryParse(val, out tmpDate);
Rufus L.
źródło
Próbowałem już, ale 3.5 jest prawidłową datą i prawidłową liczbą dziesiętną, więc to wcale nie pomaga.
Munawar,
1
W powyższym kodzie isDatejest to falsespowodowane tym, że obejmuje on sprawdzenie isDecimal. Czy nie o to prosiłeś?
Rufus L,
2
@Munawar - dokładnie „3.5 jest prawidłową datą i prawidłową liczbą dziesiętną”. Jeśli my, jako ludzie, otrzymamy ten ciąg znaków i żaden inny kontekst, nie wiemy, czy miała to być data, liczba dziesiętna czy też coś innego . Nie możesz oczekiwać, że komputer magicznie uzyska na nie odpowiedź.
Damien_The_Unbeliever
Tak, ta odpowiedź jest specyficzna dla problemu i rozwiązuje mój problem, chociaż ParseExact najlepiej pasuje, jeśli znane są formaty.
Munawar,
Problem nadal występuje, gdy format daty to „12122019”
Athanasios Kataras,
6

Sprawdź oficjalną dokumentację dotyczącą ParseExact

Jeśli znasz dokładną reprezentację, możesz zrobić coś takiego:

  format = "ddd dd MMM yyyy h:mm tt zzz";
  try {
     result = DateTime.ParseExact(dateString, format, provider);
     Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
  }
  catch (FormatException) {
     Console.WriteLine("{0} is not in the correct format.", dateString);
  }

Jeśli tego nie wiesz, utkniesz w przekonaniach kulturowych

Analizuj ciąg daty i godziny, używając konwencji określonej kultury. Przeciążenie parsowania (ciąg, IFormatProvider) (zobacz Konwertowanie i konwencje kulturowe)

Athanasios Kataras
źródło
Format nie jest znany, może być dowolny na podstawie preferencji użytkownika.
Munawar,
1
@Munawar, jak w tej sytuacji rozróżnisz 1/3/2019 i 3/1/2019?
Blaise,
@Athanasios, aplikacja jest używana dla różnych regionów i dat przechowywanych zaszyfrowanych. ponieważ użytkownik może zmienić formaty daty, więc nie chcę zadzierać z zastosowaniem określonego formatu, chociaż ParseExact najlepiej pasuje, jeśli format jest znany.
Munawar,