Wie kann ich mit DateTime die späteste Tageszeit angeben?

76

Ich verwende ein System.DateTimeObjekt, damit ein Benutzer einen Datumsbereich auswählen kann. Der Benutzer kann ein Datum (nicht eine Uhrzeit) nur mithilfe eines Kalenders eines Drittanbieters auswählen. Daher muss ich automatisch die Uhrzeit angeben, die nach dem Datum verwendet werden soll (dh: 00:00:00 oder 23:59:59) ist gewählt.

Wie kann ich die Zeit angeben, nachdem das Datum bereits von der Kalenderauswahl als DateTime-Objekt gespeichert wurde? Ich könnte die AddHours, AddMinutes, AddSecondsMethoden verwenden, aber diese beziehen sich auf die aktuelle Zeit, die möglicherweise nicht 00:00:00 ist.

Sie startDatemüssen eine Zeit von 00:00:00 und endDateeine Zeit von 23:59:59 haben, um die gesamten Tage zu berücksichtigen.

Joe Phillips
quelle
Späteste Tageszeit ist 23: 59: 59.999?
Eppz
Was meinst du mit "späteste Tageszeit"?
Daniel A. White
So präzise es auch sein mag (aber wirklich, Sekunden sollten in Ordnung sein)
Joe Phillips
@ d03boy: Was meinst du mit "Zeit ändern"? Meinen Sie damit, die PC-Uhr auf diese Zeit einzustellen?
Jon B

Antworten:

105

Wenn Sie bereits ein DateTimeObjekt erstellt haben und die Uhrzeit durch die Uhrzeit für das angegebene Datum um 23:59:59 Uhr ersetzen möchten, können Sie die .DateEigenschaft verwenden, um das Datum mit der auf 00:00:00 Uhr eingestellten Uhrzeit abzurufen und dann die Stunden hinzuzufügen. Minuten und Sekunden. Zum Beispiel:

var dt = yourDateInstance.Date.AddHours(23).AddMinutes(59).AddSeconds(59);

Wenn Sie bis spätestens 23:59:59 Uhr meinen, sollte dies auch funktionieren:

var dt = new DateTime(Now.Year, Now.Month, Now.Day, 23, 59, 59);
Jose Basilio
quelle
Tatsächlich. Es gibt nichts, was besagt, dass Sie Now.XXX verwenden müssen, um ein Jahr, einen Monat, einen Tag, eine Stunde, eine Minute oder eine Sekunde zu generieren. Sie können eine DateTime erstellen, die eine bestimmte Zeitinstanz darstellt.
Thomas Owens
Was ist, wenn ich nicht ganz sicher bin, ob es bereits auf 00:00:00 eingestellt ist? Kann ich es direkt auf eine Zeit einstellen, anstatt relativ zu sein?
Joe Phillips
1
Ja, die Eigenschaft .Date gibt die Datumskomponente mit der auf 00:00:00 eingestellten Zeit zurück. Aus diesem Grund lautet der Code: youDateInstance.Date, bevor die Stunden hinzugefügt werden.
Jose Basilio
Sehr gut! Danke für die Erklärung. Vielleicht möchten Sie das zu Ihrer Antwort für uns Neulinge hinzufügen, die es möglicherweise nicht bemerken.
Joe Phillips
12
Technisch gesehen würde die "späteste Zeit des Tages" auch die maximale Anzahl von Ticks haben. Die schnellste Antwort geben: DateTime.Today.AddDays (1) .AddTicks (-1);
Peter Drier
79

Um den letzten Augenblick für heute zu bekommen:

DateTime d = new DateTime(Now.Year, Now.Month, Now.Day);
d = d.AddDays(1);
d = d.AddTicks(-1);

Als Antwort auf Ihre Bearbeitung würde ich Folgendes tun:

DateTime start = new DateTime(Now.Year, Now.Month, Now.Day);
DateTime end = start.AddDays(1).AddTicks(-1);

// Or - just use end = start.AddDays(1), and use a < for comparison
Jon B.
quelle
+1. Ich dachte genau das Gleiche. Haben Sie alle eine spezielle Tastatur mit integriertem SO-Intellisense / Auto-Vervollständigung?
Erich Mirabal
AddDays (1) setzt es dann am nächsten Tag auf 00:00:00?
Joe Phillips
@ d03boy: genau. AddDays () wird genau 24 Stunden später sein. In diesem Fall um 00: 00: 00.0. Wenn Sie den Moment zuvor haben möchten, subtrahieren Sie einen Tick.
Jon B
2
Dies setzt voraus, dass die Zeit bereits auf 00:00:00 eingestellt ist, was hier möglicherweise keine sichere Annahme ist. Kannst du die Zeit irgendwie direkt einstellen?
Joe Phillips
1
@ d03boy Jon B hat eine DateTime durch Angabe von Jahr, Monat und Tag instanziiert. Dadurch wird die Zeit auf 0 gesetzt, sodass in diesem Fall vor dem Hinzufügen eines Tages kein Hinzufügen von .Date erforderlich ist.
Meta-Knight
20
DateTime d = DateTime.Today.AddDays(1).AddTicks(-1);
Peter Drier
quelle
12

Ihre Frage wurde bereits beantwortet, aber meiner Meinung nach ist es besser, nicht zu versuchen, einen Tick, eine Sekunde oder was auch immer vom Ende des Bereichs zu subtrahieren und mit weniger als zu vergleichen.

Wenn Sie also alle Daten in einem inklusiven Bereich von startDate bis endDate haben möchten und die Uhrzeit ignorieren möchten, können Sie in C # Folgendes verwenden:

if ((myDate >= startDate.Date) && (myDate < endDate.Date.AddDays(1)))
{
    // ... it's in the range
}

oder in T-SQL, vorausgesetzt, Ihr @StartDate und @EndDate sind genau Mitternacht, so etwas wie:

WHERE SomeDate >= @StartDate AND SomeDate < DATEADD(d,1,@EndDate)

AKTUALISIEREN

Das Beispiel wurde aktualisiert, um einen inklusiven Bereich als Antwort auf Kommentare anzuzeigen.

Joe
quelle
IMO, endDate sollte weiterhin in die Suche einbezogen werden. Was ist, wenn ich den 2. und 2. Juni als Start- und Enddatum wähle?
Joe Phillips
Dann könnten Sie einfach einen Tag zu endDate hinzufügen und Joes Code verwenden ;-)
Meta-Knight
6
DateTime startDate = DateTime.Today;
DateTime stopDate = startDate.AddDays(1).AddTicks(-1);

Als Hinweis: DateTime.TodayRückgabe (von MSDN)

Eine System.DateTime, die auf das heutige Datum eingestellt ist, wobei die Zeitkomponente auf 00:00:00 eingestellt ist.

Fügen Sie also, wie andere angemerkt haben, einen Tag hinzu, subtrahieren Sie dann das kleinste Zeitquantum (ein Häkchen) und Sie erhalten die letztmögliche Zeit für den aktuellen Tag.

Natürlich müssen Sie möglicherweise über Zeitzonen und dergleichen nachdenken, je nachdem, wo der Code ausgeführt wird und wo sich der Benutzer befindet. Die UTC-Zeit mag gut sein, aber das könnte Sie einen Tag (so oder so) stören, je nachdem, wo Ihr Code ausgeführt wird.

Erich Mirabal
quelle
Schön, dass Sie an Zeitzonen denken. Dafür wurde gesorgt.
Joe Phillips
5

Basierend auf den anderen Antworten habe ich diese praktische Erweiterungsmethode erstellt:

public static class DateTimeExtensions
{
    public static DateTime EndOfDay(this DateTime dateTime)
    {
        return dateTime.Date.AddDays(1).AddTicks(-1);
    }
}
Hein Andre Grønnestad
quelle
2

Zum Beispiel

DateTime.Now.Date.AddDays(1).AddSeconds(-1)

Oder AddTicks/AddMilliseconds/AddMinutes... basierend auf der Präzision, die Sie benötigen.

0x49D1
quelle
2

Warum nicht die Erweiterung ToDayEnd () ?

/// <summary>
    /// Gets the value of the End of the day (23:59)
    /// </summary>
    /// <param name="target"></param>
    /// <returns></returns>
    public static DateTime ToDayEnd(this DateTime target)
    {
        return target.Date.AddDays(1).AddMilliseconds(-1);
    }

Aber wenn Sie wirklich das absolute Ende des Tages meinen würden, dann ist AddTicks (-1) die Antwort.

akd
quelle
In welcher Bibliothek ist das?
Joe Phillips
Oh mein schlechtes ... es war eine der Bibliotheken, die ich benutzte. Ich habe es so oft benutzt, dass ich dachte, es sei Teil des Sytem.DateTime :)
akd
Hehe. Dachte, das könnte der Fall sein
Joe Phillips
@JoePhillips Sie können erkennen, dass dies eine Erweiterungsmethode ist, 1 es ist statisch, 2 in den Argumenten, die im Schlüsselwort this übergeben werden.
Ken
@ Ken Ich stimme zu. Das sagt mir aber nicht, welche Bibliothek ich importieren müsste, um sie zu verwenden. Es könnte eine benutzerdefinierte Bibliothek sein oder es könnte sich im .net-Framework befinden
Joe Phillips
1

yourDateInstance.CloseDate = yourDateInstance.CloseDate.Date.AddDays (1) .AddMilliseconds (-1);

Dunwan
quelle
1

Verwenden einer Erweiterungsmethode

public static DateTime EndOfTheDay(this DateTime date)
{
    return new DateTime(date.Year, date.Month, date.Day).AddDays(1).AddTicks(-1);
}

Das Ergebnis hier liefert Ihnen die spätestmögliche Zeit, indem Sie den Beginn des Tages ermitteln. Fügen Sie einen Tag hinzu und subtrahieren Sie dann einen Tick. Andere Methoden fügen Stunden, Minuten und Sekunden hinzu. Diese Lösungen in Abhängigkeit von den Codefunktionen verursachen jedoch jederzeit Probleme zwischen 23: 59: 59.000000 und 23: 59: 59.999999

Wenn ich beispielsweise wissen möchte, ob ein Wert vor einem bestimmten Enddatum / einer bestimmten Endzeit liegt, besteht bei anderen Lösungen die Möglichkeit, dass Werte im Millisekundenbereich fehlen.

Ken
quelle
Sehr saubere, wiederverwendbare Lösung. Microsoft hat große Dokumentation Erweiterungsmethoden auf die Umsetzung hier .
Smitty-Werben-Jager-Manjenson
0

benutze das

DateTime YourNewDate = new DateTime (YourDate .Year, YourDate .Month, YourDate .Day, 23, 59, 59, 99);

Mohammad Javad Tavakoli
quelle
Können Sie uns etwas mehr erklären?
Dieter Meemken
Dies entspricht dem zweiten Teil der akzeptierten Antwort.
Chris Schiffhauer
0

Dadurch erhalten Sie das erwartete Ergebnis:

DateTime startDate= DateTime.Now.Date;
DateTime endDate= startDate.AddDays(2).Add(new TimeSpan(23, 59, 59));
//startDate: 28/9/2017 0:0:0 endDate: 29/9/2017 23:59:59
Md. Tazbir Ur Rahman Bhuiyan
quelle
1
Während Ihr Code funktioniert, kann er Probleme verursachen - das Ende des Tages ist nicht 23:59:59, es sei denn, Ihre Bedeutung ist in Sekunden angegeben. Wenn sich die DateTime-Daten jedoch in (Millisekunden) befinden, ist es am besten, Millisekunden als signifikanten Wert einzuschließen. DateTime wird ebenfalls als Millisekundenwert im Speicher gespeichert. [Millisekunden vom 1. Januar 1970].
Ken