ASP.NET ist eine Reihe von Webtechnologien. C # ist eine Sprache. Sie müssen wirklich in Bezug auf einfaches .NET darüber nachdenken. Nun, für "nächsten Dienstag" - ist das "der erste Dienstag nach heute"? Wenn es Montag wäre und jemand sagte "Bis nächsten Dienstag", würde ich erwarten, dass dies 8 Tage Zeit bedeutet anstatt 1. Was ist, wenn heute ein Dienstag ist? Welche Tageszeit brauchst du?
Jon Skeet
Wenn heute Dienstag ist, möchten Sie das Datum finden, an dem der nächste Dienstag ist? Oder ist heute Montag, möchten Sie den 2. Dienstag ab Montag finden?
Feuer Panda
Der nächste Dienstag für jeden Tag.
Brenjt
2
@brenjtL: Und wenn es schon Dienstag ist?
Jon Skeet
Wenn schon Dienstag dann am selben Tag
brenjt
Antworten:
371
Wie ich in den Kommentaren erwähnt habe, gibt es verschiedene Dinge, die Sie mit "nächster Dienstag" meinen könnten, aber dieser Code gibt Ihnen "den nächsten Dienstag oder heute, wenn es bereits Dienstag ist":
DateTime today =DateTime.Today;// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysUntilTuesday =((int)DayOfWeek.Tuesday-(int) today.DayOfWeek+7)%7;DateTime nextTuesday = today.AddDays(daysUntilTuesday);
Wenn Sie "eine Woche Zeit" angeben möchten, wenn es bereits Dienstag ist, können Sie Folgendes verwenden:
// This finds the next Monday (or today if it's Monday) and then adds a day... so the// result is in the range [1-7]int daysUntilTuesday =(((int)DayOfWeek.Monday-(int) today.DayOfWeek+7)%7)+1;
... oder Sie könnten die Originalformel verwenden, aber ab morgen:
DateTime tomorrow =DateTime.Today.AddDays(1);// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysUntilTuesday =((int)DayOfWeek.Tuesday-(int) tomorrow.DayOfWeek+7)%7;DateTime nextTuesday = tomorrow.AddDays(daysUntilTuesday);
EDIT: Nur um dies schön und vielseitig zu machen:
publicstaticDateTimeGetNextWeekday(DateTime start,DayOfWeek day){// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]int daysToAdd =((int) day -(int) start.DayOfWeek+7)%7;return start.AddDays(daysToAdd);}
So erhalten Sie den Wert für "heute oder in den nächsten 6 Tagen":
Wow, ich habe mich nur gefragt, wie ich bis zum nächsten Dienstag n-te Tage bekommen könnte, und Sie haben dann Ihre Antwort mit einem Beispiel Nizza aktualisiert. Danke
brenjt
Es war schwer, die richtige Antwort zu wählen. Aber deine scheint die vielseitigste zu sein und du hast es leicht verständlich gemacht. Danke für deine Hilfe.
Brenjt
1
@brenjt: Eigentlich würde ich sagen, dass Sven's vielseitiger ist, da Sie den Wochentag angeben können, aber es ist Ihr Anruf :) (Ich habe meinen jetzt bearbeitet, um eine allgemeinere Version zu erhalten.)
Jon Skeet
1
Die +7)%7Lösung ist allerdings ziemlich gut. Obwohl der Grund, warum ich das nicht benutzt habe, darin besteht, dass es ein bisschen wie eine Mikrooptimierung ist und zu leicht, um etwas falsch zu machen (und die Lesbarkeit zu beeinträchtigen), imho natürlich.
Sven
Ein Komponententest: [TestMethod] public void ShouldGetNextSaturday () {var now = DateTime.Now; var test = GetNextWeekday (DateTime.Today, DayOfWeek.Saturday); Assert.IsTrue (now.Day <test.Day, "Der erwartete Monatstag ist nicht hier."); Assert.IsTrue (test.DayOfWeek == DayOfWeek.Saturday, "Der erwartete Wochentag ist nicht hier."); Assert.IsTrue ((test.Day - now.Day) <7, "Das erwartete Tagesintervall ist nicht hier."); }
Rasx
67
Dies sollte den Trick tun:
staticDateTimeGetNextWeekday(DayOfWeek day){DateTime result =DateTime.Now.AddDays(1);while( result.DayOfWeek!= day )
result = result.AddDays(1);return result;}
Tolle Resonanz, wenn heute Dienstag ist (was es ist ha), wird dies heute oder am nächsten Dienstag zurückkehren?
Brenjt
3
Dies wird am nächsten Dienstag zurückkehren. Wenn Sie möchten, dass es heute zurückgegeben wird, entfernen Sie es einfach .AddDays(1)aus der ersten Zeile. Auf diese Weise wird es auch DateTime.Nowselbst überprüft .
Sven
7
Es gibt weniger ausführliche und cleverere / elegantere Lösungen für dieses Problem, aber die folgende C # -Funktion funktioniert in einer Reihe von Situationen sehr gut.
/// <summary>/// Find the closest weekday to the given date/// </summary>/// <param name="includeStartDate">if the supplied date is on the specified day of the week, return that date or continue to the next date</param>/// <param name="searchForward">search forward or backward from the supplied date. if a null parameter is given, the closest weekday (ie in either direction) is returned</param>publicstaticDateTimeClosestWeekDay(thisDateTime date,DayOfWeek weekday,bool includeStartDate =true,bool? searchForward=true){if(!searchForward.HasValue&&!includeStartDate){thrownewArgumentException("if searching in both directions, start date must be a valid result");}var day = date.DayOfWeek;intadd=((int)weekday -(int)day);if(searchForward.HasValue){if(add<0&& searchForward.Value){add+=7;}elseif(add>0&&!searchForward.Value){add-=7;}elseif(add==0&&!includeStartDate){add= searchForward.Value?7:-7;}}elseif(add<-3){add+=7;}elseif(add>3){add-=7;}return date.AddDays(add);}
Die einzige Antwort, die als Erweiterung von DateTime implementiert wird. Während die anderen Lösungen alle funktionieren, erzeugt es als Erweiterungsmethode den am einfachsten zu verwendenden Code.
Wenn heute Montag ist, ergibt die von Ihnen angegebene Antwort eine Woche ab Dienstag und nicht ab morgen.
Tony
5
@ Jon Skeet gute Antwort.
Für den vorherigen Tag:
privateDateTimeGetPrevWeekday(DateTime start,DayOfWeek day){// The (... - 7) % 7 ensures we end up with a value in the range [0, 6]int daysToRemove =((int) day -(int) start.DayOfWeek-7)%7;return start.AddDays(daysToRemove);}
Beachten Sie, dass diese Lösung negative Zahlen enthält, die dem Modulo-Operator übergeben werden. In dem Wikipedia-Artikel über den Modulo-Operator heißt es: "Wenn entweder a oder n negativ ist, bricht die naive Definition zusammen und die Programmiersprachen unterscheiden sich in der Definition dieser Werte." Während dies wahrscheinlich in C # funktioniert, wäre eine mathematisch „solidere“ Lösung, um das gleiche Ergebnis zu erzielen, das Vertauschen der folgenden DayOfWeekWerte:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
Sehr einfaches Beispiel zum Einschließen oder Ausschließen des aktuellen Datums. Sie geben das Datum und den Tag der Woche an, an der Sie interessiert sind.
publicstaticclassDateTimeExtensions{/// <summary>/// Gets the next date./// </summary>/// <param name="date">The date to inspected.</param>/// <param name="dayOfWeek">The day of week you want to get.</param>/// <param name="exclDate">if set to <c>true</c> the current date will be excluded and include next occurrence.</param>/// <returns></returns>publicstaticDateTimeGetNextDate(thisDateTime date,DayOfWeek dayOfWeek,bool exclDate =true){//note: first we need to check if the date wants to move back by date - Today, + diff might move it forward or backwards to Today//eg: date - Today = 0 - 1 = -1, so have to move it forwardvar diff = dayOfWeek - date.DayOfWeek;var ddiff = date.Date.Subtract(DateTime.Today).Days+ diff;//note: ddiff < 0 : date calculates to past, so move forward, even if the date is really old, it will just move 7 days from date passed in//note: ddiff >= (exclDate ? 6 : 7) && diff < 0 : date is into the future, so calculated future weekday, based on dateif(ddiff <0|| ddiff >=(exclDate ?6:7)&& diff <0)
diff +=7;//note: now we can get safe values between 0 - 6, especially if past dates is being used
diff = diff %7;//note: if diff is 0 and we are excluding the date passed, we will add 7 days, eg: 1 week
diff += diff ==0& exclDate ?7:0;return date.AddDays(diff);}}
einige Testfälle
[TestMethod]publicvoidTestNextDate(){var date =newDateTime(2013,7,15);var start = date;//testing same month - forwardOnlyAssert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//16Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//17Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//18Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Friday));//19Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Saturday));//20Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Sunday));//21Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Monday));//22//testing same month - include dateAssert.AreEqual(start = date, date.GetNextDate(DayOfWeek.Monday,false));//15Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday,false));//16Assert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday,false));//17//testing month change - forwardOnly
date =newDateTime(2013,7,29);
start = date;Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//30Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//31Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//2013/09/01-month increasedAssert.AreEqual(start.AddDays(1), date.GetNextDate(DayOfWeek.Friday));//02//testing year change
date =newDateTime(2013,12,30);
start = date;Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Tuesday));//31Assert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Wednesday));//2014/01/01 - year increasedAssert.AreEqual(start = start.AddDays(1), date.GetNextDate(DayOfWeek.Thursday));//02}
Ich habe nach einigen umfangreichen Tests zusätzliche Änderungen gegenüber der ursprünglichen Antwort vorgenommen. Dies berechnet nun sicher den nächsten Tag basierend auf dem verwendeten Datum, der Vergangenheit, der Gegenwart und der Zukunft. Alle vorherigen Beispiele waren großartig, scheiterten aber unter bestimmten Bedingungen. Ich habe es nicht zu einer einzeiligen Aussage gemacht, damit zusätzliche Kommentare zu den Berechnungen abgegeben werden können. Der positive Fall von Jon Skeet war großartig, obwohl der Fall, den ich hatte, darin bestand, einen Tag von einem Datum zurück zu ziehen, aber immer noch größer als heute, und was ist, wenn er auf heute oder gestern verschoben wird ... das hat es gelöst.
AJB
1
Es könnte auch eine Erweiterung sein, alles hängt davon ab
publicstaticclassDateTimeExtensions{publicstaticIEnumerable<DateTime>Next(thisDateTime date,DayOfWeek day){// This loop feels expensive and useless, but the point is IEnumerablewhile(true){if(date.DayOfWeek== day){yieldreturn date;}
date = date.AddDays(1);}}}
Verwendung
var today =DateTime.Today;foreach(var monday in today.Next(DayOfWeek.Monday)){Console.WriteLine(monday);Console.ReadKey();}
Antworten:
Wie ich in den Kommentaren erwähnt habe, gibt es verschiedene Dinge, die Sie mit "nächster Dienstag" meinen könnten, aber dieser Code gibt Ihnen "den nächsten Dienstag oder heute, wenn es bereits Dienstag ist":
Wenn Sie "eine Woche Zeit" angeben möchten, wenn es bereits Dienstag ist, können Sie Folgendes verwenden:
... oder Sie könnten die Originalformel verwenden, aber ab morgen:
EDIT: Nur um dies schön und vielseitig zu machen:
So erhalten Sie den Wert für "heute oder in den nächsten 6 Tagen":
Um den Wert für "den nächsten Dienstag außer heute" zu erhalten:
quelle
+7)%7
Lösung ist allerdings ziemlich gut. Obwohl der Grund, warum ich das nicht benutzt habe, darin besteht, dass es ein bisschen wie eine Mikrooptimierung ist und zu leicht, um etwas falsch zu machen (und die Lesbarkeit zu beeinträchtigen), imho natürlich.Dies sollte den Trick tun:
quelle
.AddDays(1)
aus der ersten Zeile. Auf diese Weise wird es auchDateTime.Now
selbst überprüft .Es gibt weniger ausführliche und cleverere / elegantere Lösungen für dieses Problem, aber die folgende C # -Funktion funktioniert in einer Reihe von Situationen sehr gut.
quelle
quelle
@ Jon Skeet gute Antwort.
Für den vorherigen Tag:
Vielen Dank!!
quelle
DayOfWeek
Werte:int daysToSubtract = -(((int)dateTime.DayOfWeek - (int)day + 7) % 7);
quelle
Sehr einfaches Beispiel zum Einschließen oder Ausschließen des aktuellen Datums. Sie geben das Datum und den Tag der Woche an, an der Sie interessiert sind.
einige Testfälle
quelle
Es könnte auch eine Erweiterung sein, alles hängt davon ab
Verwendung
quelle
Jetzt im Oneliner-Geschmack - für den Fall, dass Sie ihn als Parameter an einen Mechanismus übergeben müssen.
In diesem speziellen Fall:
quelle
Ziel C Version:
quelle