myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns
» Datenschutzerklärung
» Impressum

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » Validierung DateTime-Formatzeichenfolge
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Validierung DateTime-Formatzeichenfolge

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
inflames2k inflames2k ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 2.193
Entwicklungsumgebung: Visual Studio 2010 Express


inflames2k ist offline

Validierung DateTime-Formatzeichenfolge

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

für eine Anwendung soll dem Benutzer erlaubt werden manuell das Datumsformat anzugeben. Nach Eingabe würden wir dies gern validieren ob es sich um eine gültige Formatzeichenfolge handelt.

Wie wäre hier die beste herangehensweise?

Meine Überlegung war:
  • Formatierung aktuelles Datum mit Formatzeichenfolge
  • DateTime.TryParseExact auf den erhaltenen String
  • Wenn true => gültige Formatzeichenfolge
  • Wenn false => ungültige Formatzeichenfolge
Ich bin mir nicht sicher, ob das so passt. Gibt es eine bessere / sauberere Lösung?
11.06.2019 16:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.219
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich denke mal mit DateTime.TryParseExact dürftet ihr gut fahren.
Wenn der Bneutzer dann auch einen gültigen Format String angibt, wäre es möglich dies damit zu parsen.
Hier müsstet ihr aber auch prüfen ob ein Format gültig ist.
Dazu müsste der Benutzer auch die Möglichkeit haben sich z.B. die aktuelle Zeit mit seinem Format als Vorschau anzeigen zu lassen.
Und er bräuchte auch eine Legende um zu wissen was wie eingegeben werden kann.

Hier würde ich empfehlen ein Test Projekt anzulegen und per WinForms mal etwas rumspielen um zu schauen was möglich ist.

T-Virus
11.06.2019 17:27 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 2.193
Entwicklungsumgebung: Visual Studio 2010 Express

Themenstarter Thema begonnen von inflames2k

inflames2k ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Da fangen meine Probleme ja schon an. Es handelt sich beim Projekt um einen Converter von Eingangsdaten in das Csv-Format.

Nur für Datumswerte soll eine Formatierungszeichenfolge über die Oberfläche festgelegt werden können. - Die Validierung der Zeichenfolge gestaltet sich aber ziemlich schwierig.

Mein beschriebener Ablauf hat irgendwie merkwürdige auswüchse.

C#-Code (Beispiel mit DateTime.TryParse und eigentlich gültiger Formatzeichenfolge):
            DateTime dt = DateTime.MinValue;

            string dtAsString = dt.ToString("yyyyMMdd");

            if (!DateTime.TryParse(dtAsString, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
                 Console.WriteLine("invalid format");
            else
                Console.WriteLine(dt.ToString());
          // Ergebnis => Invalid Format obwohl gültig

Liefert eine Exception => ungültiges Datumsformat. - Bei DateTime.TryParse kann leider kein Format mitgegeben werden.

Bei TryParseExact wirds aber erst richtig lustig. Vergebe ich dort nämlich ein ungültiges Format kommt das aktuelle Datum als Ergebnis raus und es gibt keinen Fehler / keine Exception.

C#-Code (Beispiel mit DateTime.TryParseExact und ungültiger Formatzeichenfolge):
            DateTime dt = DateTime.MinValue;

            string dtAsString = dt.ToString("ab");

            if (!DateTime.TryParseExact(dtAsString, "ab", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
                 Console.WriteLine("invalid format");
            else
                Console.WriteLine(dt.ToString()); // 13.06.2019 ? wtf???
13.06.2019 14:14 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 12.721
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ist in der Dokumentation beantwortet.

Zitat von https://docs.microsoft.com/en-us/dotnet/api/system.datetime.parseexact?redirectedfrom=MSDN&view=netframework-4. 8#System_DateTime_ParseExact_System_String_System_String_System_IFormatProv
ider_:
If format defines a date with no time element and the parse operation succeeds, the resulting DateTime value has a time of midnight (00:00:00). If format defines a time with no date element and the parse operation succeeds, the resulting DateTime value has a date of DateTime.Now.Date.

"yyyyMMdd" ist kein gültiges Dateformat irgendeiner Culture. Der Parser kann auch gar nicht erkennen, was an welcher Stelle zu finden ist.
Rein vom Format wäre yyyyMMdd mit ddMMyyyy identisch. Culture Formate haben immer Bindestriche für Datumswerte und Doppelpunkte von Uhrzeiten.

Du hast ein Custom Format, das man auch so explizit angeben muss.

PS: die korrekte Verwendung von Zeitstempeln in Dateien und Datenbanken ist übrigens DateTimeOffset.

PPS: auch TryParseExact nimmt Formate an.
13.06.2019 14:20 Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 2.193
Entwicklungsumgebung: Visual Studio 2010 Express

Themenstarter Thema begonnen von inflames2k

inflames2k ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Abt:
PPS: auch TryParseExact nimmt Formate an.

Japp, leider aber jede beliebige und erklärt sie für gültig. - Sofern es bei DateTime.ToString() nicht schon wegbricht.

DateTime.ToString("a") => Exception
DateTime.ToString("ab") => Ergebis: "ab"

Und "ab" kann ich leider auch wieder mit TryParseExact sauber parsen. Wird zwar je nach DateTimeStyles zu 01.01.0000 bzw. 13.06.2019 aber ist ja beides quatsch.

Ich glaube ich habe das Prinzip so langsam verstanden. - Solang die EIngangszeichenfolge dem Format entspricht ist es gültig. Unabhängig davon ob das Format Sinn macht oder nicht. - Eine Validierung wird damit sehr schwierig, da ja eben auch "Stunde: {0:hh}" ein durchaus gültiger String zur Formatierung ist.

Insofern hat sich das soweit erst einmal erledigt. Entweder wir definieren zuvor, was alles zulässig ist oder lassen die Validierung ganz weg.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von inflames2k am 13.06.2019 14:52.

13.06.2019 14:38 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 12.721
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von inflames2k:
Japp, leider aber jede beliebige und erklärt sie für gültig. - Sofern es bei DateTime.ToString() nicht schon wegbricht.

Les die Dokumentation. Da ist erklärt, warum.
.NET verhält sich hier absolut korrekt zur Dokumentation

Zitat von inflames2k:
DateTime.ToString("a") => Exception
DateTime.ToString("ab") => Ergebis: "ab"

Auch das ist vollständig in der Dokumentation aufgeführt.

Zitat von https://docs.microsoft.com/en-us/dotnet/api/system.datetime.tostring?view=netframework-4.8:
The length of format is 1, and it is not one of the format specifier characters defined for DateTimeFormatInfo.

Du solltest Dir die Basics für DateTime Format anschauen - und mal bei Unklarheiten in die Doku schauen.
Bisher gibt es in Deinem Code kein Anhaltspunkt, der nicht auf den ersten beiden Seiten von DateTime Format beantwortet wäre.

Auf Dein Edit:

Zitat:
Entweder wir definieren zuvor, was alles zulässig ist oder lassen die Validierung ganz weg.

Es gibt hier einen Standard: ISO 8601. Das DateTime Format ist dafür "o"

Auch das steht in der Dokumentation:

Zitat von https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings#the-round-trip-o-o-format-specifier:
The "O" or "o" standard format specifier represents a custom date and time format string using a pattern that preserves time zone information and emits a result string that complies with ISO 8601.
13.06.2019 14:56 Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 2.193
Entwicklungsumgebung: Visual Studio 2010 Express

Themenstarter Thema begonnen von inflames2k

inflames2k ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Abt,

das ist mir ja alles klar. Ist ja aber auch nicht mein eigentliches Problem. Ich will ja nicht prüfen ob Datum X gütig ist. Das weiß ich an der Stelle.

Ich möchte prüfen ob die eingegebene Formatzeichenfolge gültig ist. - Und das ist sie eigentlich immer sobald sie mindestens 2 Stellig ist.

Insofern sieht die einzig sinnvolle Validierung so aus, dass geprüft wird ob bei DateTime.ToString(format) eine Exception geworfen wird oder nicht.
13.06.2019 15:12 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 12.721
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von inflames2k:
Und das ist sie eigentlich immer sobald sie mindestens 2 Stellig ist.

Nope, mind. 2 stellig und ein gültiger Identifier.

Es ist aber nicht möglich mit 100% Gewissheit zu erkennen, welche Zahlenkombination welches Format erfüllt.
19071907 kann yyyyddMM sein, aber auch ddMMyyy (und da gibt es unendlich Kombinationen).

Daher braucht der Parser zwingend beim Datum den (i.d.R.) Bindestrich, um den Aufbau zu erkennen.
Und das geht simpel mit DateTime.TryParse(), das kein Fallback hat.
13.06.2019 15:15 Beiträge des Benutzers | zu Buddylist hinzufügen
inflames2k inflames2k ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3407.gif


Dabei seit: 03.01.2010
Beiträge: 2.193
Entwicklungsumgebung: Visual Studio 2010 Express

Themenstarter Thema begonnen von inflames2k

inflames2k ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hier wiederspreche ich klar, dass die Formatzeichenfolge 2 stellig sein und einen gültigen Identifier besitzen muss. Zumindest was die Implementierung angeht. Denn "[[" ist sowohl bei ToString() als auch bei TryParseExact gültig.

Um noch mal ganz klar zu Erläutern was mein Ziel ist:

Über eine Konfigurationsoberfläche kann eine Formatzeichenfolge eingegeben werden. Meinetwegen "dd.MM.yyyy". Beim Speichern der Konfiguration soll geprüft werden ob "dd.MM.yyyy" eine gültige Formatzeichenfolge ist. Es liegt an der Stelle also kein Datum vor, dass irgendwie formatiert werden soll und keine Zeichenfolge die in ein DateTime umgewandelt werden soll.

Wenn es nur um die Prüfung ginge ob eine Zeichenfolge ein bestimmtes Datumsformat besitzt hätte ich ja keine Probleme. Das ist alles fein beschrieben. Aber ist ja eben nicht mein Problem.
13.06.2019 15:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 12.721
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von inflames2k:
Zumindest was die Implementierung angeht. Denn "[[" ist sowohl bei ToString() als auch bei TryParseExact gültig.

Nein ist es nicht. TryParse liefert ein False und TryParseExact korrektweise den in der Doku beschriebenen Fallback-Wert.
Und nur weil der Fallback-Fall zutrifft, ist es noch lang nicht gültig - steht auch in der Doku.

ToString liefert Dir keinen Fehler, weil dieser in der Dokumentation genannter Fall eintritt:

Zitat von https://docs.microsoft.com/de-de/dotnet/standard/base-types/custom-date-and-time-format-strings:
Any other character - The character is copied to the result string unchanged.

Les einfach mal die Dokumentation dazu - da steht es exakt drin (kA wie oft man Dir das noch sagen muss).
Wir haben sogar die notwendigen Textstellen freundlicherweise aus der Doku raus kopiert...
13.06.2019 15:37 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 16.06.2019 11:08