Laden...

DateTime-Werte in ein DateTime zusammenführen

Erstellt von Arre vor 5 Jahren Letzter Beitrag vor 5 Jahren 2.170 Views
A
Arre Themenstarter:in
6 Beiträge seit 2018
vor 5 Jahren
DateTime-Werte in ein DateTime zusammenführen

Liebe Schwarmintelligenz!

Ich habe folgendes Problem. Ich möchte ein Formular erstellen, in dem ich Termine mit Datum, Uhrzeit des Beginns und des Endes eingeben kann.

Nun möchte ich, dass folgendermaßen:

  • Einen DateTimePicker zur Erstellung des Datums.
  • Einen DateTimePicker zur Erstellung der Uhrzeit des Termin-Beginns.
  • und einen DateTimePicker um das Ende des Termins festzulegen.

Das Datum (Jahr,Monat und Tag) und die Uhrzeiten sollen anschließend aber ein einer DateTime zusammengeführt werden (also die Werte für Jahr, Monat und Tag aus dateTimePicker 1 PLUS die Werte für die Uhrzeit aus DateTimePicker 2. Das wären die Werte, die ich für den Beginnzeitpunkt brauche. Entsprechend dann nochmal für das Ende des Termins).

Das kriege ich nicht hin. Wenn ich ein Objekt als DateTime erstelle und probiere einzelne Werte zuzuweisen, gibt er mir eine Fehlermeldung aus. Beispielcode:

DateTime Termin = new DateTime();
Termin.Year = dateTimePickerDatumTermin.Year;

Hat jemand eine Idee wie ich das lösen könnte?
Nochmal auf den Punkt gebracht: Wie füge ich Werte aus zwei DateTimePickern zusammen?

Screenshots der Ausgabe und den Quelltext hänge ich an.

Vielen Dank im Voraus!
Arre

P
441 Beiträge seit 2014
vor 5 Jahren

Das DateTime Struct ist nach der Initialisierung mit einem Wert nicht mehr beschreibbar.
D.h., wenn du die Zeit oder das Datum verändern willst, muss du ein neues DateTime Objekt erstellen.

Das kannst du über zwei Wege:
-> Über die Add*() Methoden (z.B. AddHours())
-> Durch addieren eines TimeSpan Objektes

Dabei musst du beachten, dass ein DateTime Objekt immer beides enthält: Datum und Zeit, willst du eine Uhrzeit auf ein bereits bestehendes DateTime Objekt festlegen, kannst du die Property Date des Nutzen.

z.B. so:


DateTime termin = DateTime.Now; 
DateTime zeit = DateTime.Now.AddHours(1.0);

DateTime terminUndZeit = termin.Date.AddHours(zeit.Hour).AddMinutes(zeit.Minutes).AddSeconds(zeit.Seconds);

T
2.224 Beiträge seit 2008
vor 5 Jahren

Das Problem ist hier eben wieder das Verhalten von Wertetypen, also im Grund den Structs.
Wie Papst schon sagt, musst du der Ergebnis einer Äderung am DateTime immer in einem anderen DateTime speichern.

Besser wäre es aber, wenn du bei Zeiten vom DateTime direkt auf TimeOfDay zugreifst, wenn du nur die Zeit aus einem DateTime brauchst.


DateTime termin = DateTime.Now;
DateTime zeit = DateTime.Now.AddHours(1.0);
DateTime terminUndZeit = termin.Date.Add(zeit.TimeOfDay);

Dein DateTimePicker gibt dir auch schon als Ergebnis der Auswahl ein DateTime Objekt i.d.R. zurück.
Entsprechend musst du aus deinen DateTime Pickern dann nur noch die Ergebnisse einsammeln und entsprechend die Zeiten auf den Tag rechnen.

Du solltest dir aus deinem Code auch unnötige Initalisierungen sparen.


// Unnötige Werteinitalisierung, die verworfen wird!
DateTime Termin = new DateTime();
Termin = dateTimePicker.Value;

// Variable erstellen und den Wert direkt zuweisen!
DateTime Termin2 = dateTimePicker.Value;

Gerade wenn du später deinen Code umbaust und dann vergisst einen Wert zuzuweisen, suchst du dich durch einen Code um festzustellen, dass du die Variable nicht mit dem gewünschten Wert initalisiert hast.

Auch solltest du Variablen nicht Großschreiben und die Benennung sollte auch klarer sein.
Anstelle von Termin, dann datum/tag und zeitVon/zeitBis.

Nachtrag:
Auch kannst du dir die Umwandlung von sender in den Events sparen.
Da die Events explizit für ein bestimmtes Controll umgesetzt wurde, kannst du auch direkt auf das Controll zugreifen.
Halte ich für einen besseren Stil, da Sender in diesem Fall immer auf ei explizites Control bezogen ist.
Wenn du aber z.B. ein Event für mehrere Controls verwendest, wäre dies der saubere Weg.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

P
441 Beiträge seit 2014
vor 5 Jahren

DateTime.TimeOfDay ist tatsächlich die bessere Lösung. Kannte ich gar nicht - habe ich noch nie gebraucht etwas derartiges 😃

T
2.224 Beiträge seit 2008
vor 5 Jahren

@Papst
Dann schau dir mal die ganze DateTime Doku an.
Ist wirklich sehr genial gemacht.
Dort hat man wirklich eine Fülle an Properties um mit vielen Formen von Date und Time zu arbeiten.
Auch die Ermittlung des Wochentages etc. ist direkt über DateTime möglich.

Da ich DateTime häufig für Auswertungszeiträume oder mal für Tages- und Zeitbezogene Sonderfälle brauche, habe ich dort schon fast alle Properties mindestens einmal genutzt.
Berechnungen mit Datum und Uhrzeit sind in C# so genial umgesetzt, dass ich keine bessere Umsetzung als in .NET kenne. 😃

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

16.834 Beiträge seit 2008
vor 5 Jahren

Ich will jetzt Deine Euphorie nur ungern bremsen, T-Virus - aber die DateTime API gehört zu den mit umstrittensten Bereiche im .NET Umfeld; und einige zumindest fragwürdige Umsetzungen.

Google mal nach "Mr DateTime" Jon Skeet und seiner NodaTime Bibliothek.... das ist deutlich besser (meine Meinung, und durchaus auch die eines großen Teils der .NET Community) implementiert und bügelt einige Schwachstellen aus.
Es gibt auch auf YouTube einige Videos zu seinen Konferenzen über DateTime vs NodaTime und seinem Talk "More fun with DateTime".

Siehe auch nodatime: What's wrong with DateTime anyway

T
2.224 Beiträge seit 2008
vor 5 Jahren

@Abt
Danke für den Link.
Muss aber gestehen, dass ich in 10 Jahren mit .NET noch nie von NodaTime gehört habe und auch nie jemand getroffen hatte, der sich über die DateTime API beschwert hätte oder auf alternativen gearbeitet hätte.
Die im Link angesprochenen Probleme kann ich nachvollziehen, spielen in meinem Umfeld nur leider keine große Rolle.

Primär arbeite ich mit DateTime entweder als Zeitstempel oder eben als Zeiträume mit lokaler oder UTC Zeit.
Entsprechend ist mein aktueller Anwendungsfall mit DateTime vermutlich auch sehr eingeschränkt.

Ich persönlich würde auch weiterhin mit DateTime arbeiten, da ich eigentlich keine Fälle habe in denen eine andere API/Lib besser wäre um mit Datum/Uhrzeiten zu arbeiten.
Da ich aber auch nur mir lokaler Zeit und ab und an UTC Zeiten arbeite, dürfte dies auch kein Problem mit der regulären API darstellen.
Ich kenne auch ehrlich gesagt keine andere Libs/Controls die etwas anderes als das reguläre DateTime anbieten.
Liegt es einfach an meinem Umfeld oder ist NodaTime eher in einem mir unbekannten Umfeld im Einsatz?
Ich würde auch keine API o.ä. kennen, die was anderes als DateTimes liefert.
Würde mich aber bei Zeiten mal in die API einlesen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

A
Arre Themenstarter:in
6 Beiträge seit 2018
vor 5 Jahren

Hallo an alle!

Erstmal vielen Dank für die raschen Antworten. Ich werde mich heute Abend mal dransetzen und probieren das umzusetzen, was ihr geschrieben habt.

Viele Grüße!

A
Arre Themenstarter:in
6 Beiträge seit 2018
vor 5 Jahren

Vielen Dank!

Es läuft!

16.834 Beiträge seit 2008
vor 5 Jahren

Primär arbeite ich mit DateTime entweder als Zeitstempel oder eben als Zeiträume mit lokaler oder UTC Zeit.

.... dann solltest Du meinen Link vllt nochmals lesen.