Wie finde ich den Beginn der Woche (sowohl Sonntag als auch Montag), wenn ich nur die aktuelle Zeit in C # kenne?
Etwas wie:
DateTime.Now.StartWeek(Monday);
Wie finde ich den Beginn der Woche (sowohl Sonntag als auch Montag), wenn ich nur die aktuelle Zeit in C # kenne?
Etwas wie:
DateTime.Now.StartWeek(Monday);
Antworten:
Verwenden Sie eine Erweiterungsmethode. Sie sind die Antwort auf alles, wissen Sie! ;)
public static class DateTimeExtensions
{
public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
{
int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
return dt.AddDays(-1 * diff).Date;
}
}
Welches kann wie folgt verwendet werden:
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);
dt
UTC und ist bereits der Anfang der Woche zum Beispiel , 2012-09-02 16:00:00Z
die ist Mon, 03 Sep 2012 00:00:00
in der Ortszeit angegeben. Es muss also auf dt
Ortszeit umgestellt oder etwas schlauer gemacht werden. Es müsste auch das Ergebnis als UTC zurückgeben, wenn die Eingabe UTC wäre.
DateTime.Parse("2012-09-02 16:00:00Z")
gibt das Äquivalent zur Ortszeit zurück, und diese Methode gibt dieselbe Zeit korrekt als Ortszeit zurück. Wenn Sie DateTime.Parse("2012-09-02 16:00:00Z").ToUniversalTime()
die UTC-Zeit explizit übergeben, gibt diese Methode 6 Tage, 16 Stunden früher, korrekt als UTC-Zeit zurück. Es funktioniert genau so, wie ich es erwartet hätte.
dt
. Ich benutzteint diff = dt.Date.DayOfWeek - startOfWeek;
Der schnellste Weg, den ich finden kann, ist:
var sunday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek);
Wenn Sie möchten, dass ein anderer Wochentag Ihr Startdatum ist, müssen Sie nur den DayOfWeek-Wert am Ende hinzufügen
var monday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Monday);
var tuesday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Tuesday);
Etwas ausführlicher und kulturbewusster:
System.Globalization.CultureInfo ci =
System.Threading.Thread.CurrentThread.CurrentCulture;
DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
DayOfWeek today = DateTime.Now.DayOfWeek;
DateTime sow = DateTime.Now.AddDays(-(today - fdow)).Date;
CultureInfo.CurrentCulture
indem Sie sie nicht so vom Faden abziehen. Scheint eine seltsame Art zu sein, darauf zuzugreifen.
Now
Unterkunft zweimal anzurufen . Wenn die aktuelle Uhrzeit zwischen den beiden Anrufen 24:00 Uhr (oder Mitternacht 12:00 Uhr) vergeht, hat sich das Datum geändert.
Verwenden von Fluent DateTime :
var monday = DateTime.Now.Previous(DayOfWeek.Monday);
var sunday = DateTime.Now.Previous(DayOfWeek.Sunday);
public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
Hässlich, aber es gibt zumindest die richtigen Daten zurück
Mit vom System eingestellter Wochenbeginn:
public static DateTime FirstDateInWeek(this DateTime dt)
{
while (dt.DayOfWeek != System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
dt = dt.AddDays(-1);
return dt;
}
Ohne:
public static DateTime FirstDateInWeek(this DateTime dt, DayOfWeek weekStartDay)
{
while (dt.DayOfWeek != weekStartDay)
dt = dt.AddDays(-1);
return dt;
}
Kombinieren wir die kultursichere Antwort und die Antwort auf die Erweiterungsmethode:
public static class DateTimeExtensions
{
public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
{
System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
return DateTime.Today.AddDays(-(DateTime.Today.DayOfWeek- fdow));
}
}
dt
statt DateTime.Today
, die Mathematik in einem wickelt (offset + 7) % 7
einen negativen Offset zu gewährleisten, eine Single-Parameter - Methode zu verwenden , Überlast , die verstreicht , die aktuelle Kultur ist FirstDayOfWeek
als startOfWeek
Argument und möglicherweise (je nach Spezifikation) zu zwingen einem Null-Offset auf einen 7-Tage-Offset, sodass "letzter Dienstag" heute nicht zurückkehrt, wenn es bereits Dienstag ist.
Dies mag ein bisschen hacken, aber Sie können die .DayOfWeek-Eigenschaft in ein int umwandeln (es ist eine Aufzählung und da der zugrunde liegende Datentyp nicht geändert wurde, wird standardmäßig int verwendet) und damit den vorherigen Wochenbeginn bestimmen .
Es scheint, dass die in der DayOfWeek-Aufzählung angegebene Woche am Sonntag beginnt. Wenn wir also 1 von diesem Wert abziehen, entspricht dies der Anzahl der Tage, die der Montag vor dem aktuellen Datum liegt. Wir müssen auch den Sonntag (0) auf 7 abbilden, also wird bei 1 - 7 = -6 der Sonntag auf den vorherigen Montag abgebildet: -
DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
DateTime startOfWeek = now.AddDays(1 - (int)now.DayOfWeek);
Der Code für den vorherigen Sonntag ist einfacher, da wir diese Anpassung nicht vornehmen müssen: -
DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
DateTime startOfWeek = now.AddDays(-(int)now.DayOfWeek);
Für Montag
DateTime startAtMonday = DateTime.Now.AddDays(DayOfWeek.Monday - DateTime.Now.DayOfWeek);
Für Sonntag
DateTime startAtSunday = DateTime.Now.AddDays(DayOfWeek.Sunday- DateTime.Now.DayOfWeek);
using System;
using System.Globalization;
namespace MySpace
{
public static class DateTimeExtention
{
// ToDo: Need to provide culturaly neutral versions.
public static DateTime GetStartOfWeek(this DateTime dt)
{
DateTime ndt = dt.Subtract(TimeSpan.FromDays((int)dt.DayOfWeek));
return new DateTime(ndt.Year, ndt.Month, ndt.Day, 0, 0, 0, 0);
}
public static DateTime GetEndOfWeek(this DateTime dt)
{
DateTime ndt = dt.GetStartOfWeek().AddDays(6);
return new DateTime(ndt.Year, ndt.Month, ndt.Day, 23, 59, 59, 999);
}
public static DateTime GetStartOfWeek(this DateTime dt, int year, int week)
{
DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
return dayInWeek.GetStartOfWeek();
}
public static DateTime GetEndOfWeek(this DateTime dt, int year, int week)
{
DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
return dayInWeek.GetEndOfWeek();
}
}
}
Alles zusammen mit der Globalisierung und die Angabe des ersten Wochentags als Teil unseres Aufrufs
public static DateTime StartOfWeek ( this DateTime dt, DayOfWeek? firstDayOfWeek )
{
DayOfWeek fdow;
if ( firstDayOfWeek.HasValue )
{
fdow = firstDayOfWeek.Value;
}
else
{
System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
fdow = ci.DateTimeFormat.FirstDayOfWeek;
}
int diff = dt.DayOfWeek - fdow;
if ( diff < 0 )
{
diff += 7;
}
return dt.AddDays( -1 * diff ).Date;
}
var now = System.DateTime.Now;
var result = now.AddDays(-((now.DayOfWeek - System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 7) % 7)).Date;
Dies würde Ihnen am ersten Sonntag der Woche Mitternacht geben:
DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, t.Hour, t.Minute, t.Second);
Dies gibt Ihnen den ersten Montag um Mitternacht:
DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek - 1, t.Hour, t.Minute, t.Second);
Versuchen Sie dies in c #. Mit diesem Code können Sie sowohl das erste als auch das letzte Datum einer bestimmten Woche abrufen. Hier ist Sonntag der erste Tag und Samstag der letzte Tag, aber Sie können beide Tage entsprechend Ihrer Kultur einstellen
DateTime firstDate = GetFirstDateOfWeek(DateTime.Parse("05/09/2012").Date,DayOfWeek.Sunday);
DateTime lastDate = GetLastDateOfWeek(DateTime.Parse("05/09/2012").Date, DayOfWeek.Saturday);
public static DateTime GetFirstDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
DateTime firstDayInWeek = dayInWeek.Date;
while (firstDayInWeek.DayOfWeek != firstDay)
firstDayInWeek = firstDayInWeek.AddDays(-1);
return firstDayInWeek;
}
public static DateTime GetLastDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
DateTime lastDayInWeek = dayInWeek.Date;
while (lastDayInWeek.DayOfWeek != firstDay)
lastDayInWeek = lastDayInWeek.AddDays(1);
return lastDayInWeek;
}
Versuchte mehrere, löste das Problem jedoch nicht mit einer Woche, die an einem Montag begann, was dazu führte, dass ich den kommenden Montag an einem Sonntag hatte. Also habe ich es ein bisschen modifiziert und es mit diesem Code zum Laufen gebracht:
int delta = DayOfWeek.Monday - DateTime.Now.DayOfWeek;
DateTime monday = DateTime.Now.AddDays(delta == 1 ? -6 : delta);
return monday;
dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
Schritt 1: Erstellen Sie eine statische Klasse
public static class TIMEE
{
public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
{
int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
return dt.AddDays(-1 * diff).Date;
}
public static DateTime EndOfWeek(this DateTime dt, DayOfWeek startOfWeek)
{
int diff = (7 - (dt.DayOfWeek - startOfWeek)) % 7;
return dt.AddDays(1 * diff).Date;
}
}
Schritt 2: Verwenden Sie diese Klasse, um sowohl den Start- als auch den Endtag der Woche zu erhalten
DateTime dt =TIMEE.StartOfWeek(DateTime.Now ,DayOfWeek.Monday);
DateTime dt1 = TIMEE.EndOfWeek(DateTime.Now, DayOfWeek.Sunday);
(6 - (dt.DayOfWeek - startOfWeek)) % 7
für mich gegen die von mir geschriebenen Unit-Tests erforderlich .
Die folgende Methode sollte die gewünschte DateTime zurückgeben. Pass in true für Sonntag als ersten Tag der Woche, false für Montag:
private DateTime getStartOfWeek(bool useSunday)
{
DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
if(!useSunday)
dayOfWeek--;
if(dayOfWeek < 0)
{// day of week is Sunday and we want to use Monday as the start of the week
// Sunday is now the seventh day of the week
dayOfWeek = 6;
}
return now.AddDays(-1 * (double)dayOfWeek);
}
Danke für die Beispiele. Ich musste immer den ersten Tag der Woche "CurrentCulture" verwenden und für ein Array musste ich die genaue Tagesnummer kennen. Hier sind meine ersten Erweiterungen:
public static class DateTimeExtensions
{
//http://stackoverflow.com/questions/38039/how-can-i-get-the-datetime-for-the-start-of-the-week
//http://stackoverflow.com/questions/1788508/calculate-date-with-monday-as-dayofweek1
public static DateTime StartOfWeek(this DateTime dt)
{
//difference in days
int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.
//As a result we need to have day 0,1,2,3,4,5,6
if (diff < 0)
{
diff += 7;
}
return dt.AddDays(-1 * diff).Date;
}
public static int DayNoOfWeek(this DateTime dt)
{
//difference in days
int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.
//As a result we need to have day 0,1,2,3,4,5,6
if (diff < 0)
{
diff += 7;
}
return diff + 1; //Make it 1..7
}
}
Niemand scheint dies noch richtig beantwortet zu haben. Ich werde meine Lösung hier einfügen, falls jemand sie benötigt. Der folgende Code funktioniert unabhängig davon, ob der erste Tag der Woche ein Montag oder ein Sonntag oder etwas anderes ist.
public static class DateTimeExtension
{
public static DateTime GetFirstDayOfThisWeek(this DateTime d)
{
CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
var first = (int)ci.DateTimeFormat.FirstDayOfWeek;
var current = (int)d.DayOfWeek;
var result = first <= current ?
d.AddDays(-1 * (current - first)) :
d.AddDays(first - current - 7);
return result;
}
}
class Program
{
static void Main()
{
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine("Current culture set to en-US");
RunTests();
Console.WriteLine();
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("da-DK");
Console.WriteLine("Current culture set to da-DK");
RunTests();
Console.ReadLine();
}
static void RunTests()
{
Console.WriteLine("Today {1}: {0}", DateTime.Today.Date.GetFirstDayOfThisWeek(), DateTime.Today.Date.ToString("yyyy-MM-dd"));
Console.WriteLine("Saturday 2013-03-02: {0}", new DateTime(2013, 3, 2).GetFirstDayOfThisWeek());
Console.WriteLine("Sunday 2013-03-03: {0}", new DateTime(2013, 3, 3).GetFirstDayOfThisWeek());
Console.WriteLine("Monday 2013-03-04: {0}", new DateTime(2013, 3, 4).GetFirstDayOfThisWeek());
}
}
Modulo in C # funktioniert schlecht für -1mod7 (sollte 6 sein, c # gibt -1 zurück), also ... sieht die "Oneliner" -Lösung so aus :)
private static DateTime GetFirstDayOfWeek(DateTime date)
{
return date.AddDays(-(((int)date.DayOfWeek - 1) - (int)Math.Floor((double)((int)date.DayOfWeek - 1) / 7) * 7));
}
Gleiches gilt für das Ende der Woche (im Stil von @Compile Dies ist die Antwort):
public static DateTime EndOfWeek(this DateTime dt)
{
int diff = 7 - (int)dt.DayOfWeek;
diff = diff == 7 ? 0 : diff;
DateTime eow = dt.AddDays(diff).Date;
return new DateTime(eow.Year, eow.Month, eow.Day, 23, 59, 59, 999) { };
}
Sie können die ausgezeichnete Umbrella-Bibliothek verwenden :
using nVentive.Umbrella.Extensions.Calendar;
DateTime beginning = DateTime.Now.BeginningOfWeek();
Aber sie haben scheinen Montag als erster Tag der Woche gespeichert zu haben (siehe die EigenschaftnVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn
), so dass frühere lokalisierte Lösung ein bisschen besser ist. Unglücklich.
Bearbeiten : Bei näherer Betrachtung der Frage sieht es so aus, als würde Umbrella auch dafür funktionieren:
// Or DateTime.Now.PreviousDay(DayOfWeek.Monday)
DateTime monday = DateTime.Now.PreviousMonday();
DateTime sunday = DateTime.Now.PreviousSunday();
Obwohl es erwähnenswert ist, dass Sie sieben Tage zurück haben, wenn Sie an einem Montag nach dem vorherigen Montag fragen. Dies gilt aber auch, wenn Sie verwenden BeginningOfWeek
, was wie ein Fehler scheint :(.
Dies gibt sowohl den Anfang der Woche als auch das Ende der Woche zurück:
private string[] GetWeekRange(DateTime dateToCheck)
{
string[] result = new string[2];
TimeSpan duration = new TimeSpan(0, 0, 0, 0); //One day
DateTime dateRangeBegin = dateToCheck;
DateTime dateRangeEnd = DateTime.Today.Add(duration);
dateRangeBegin = dateToCheck.AddDays(-(int)dateToCheck.DayOfWeek);
dateRangeEnd = dateToCheck.AddDays(6 - (int)dateToCheck.DayOfWeek);
result[0] = dateRangeBegin.Date.ToString();
result[1] = dateRangeEnd.Date.ToString();
return result;
}
Ich habe den vollständigen Code zur Berechnung von Anfang / Ende von Woche, Monat, Quartal und Jahr in meinem Blog ZamirsBlog veröffentlicht
namespace DateTimeExample
{
using System;
public static class DateTimeExtension
{
public static DateTime GetMonday(this DateTime time)
{
if (time.DayOfWeek != DayOfWeek.Monday)
return GetMonday(time.AddDays(-1)); //Recursive call
return time;
}
}
internal class Program
{
private static void Main()
{
Console.WriteLine(DateTime.Now.GetMonday());
Console.ReadLine();
}
}
}
Hier ist eine Kombination einiger Antworten. Es wird eine Erweiterungsmethode verwendet, mit der die Kultur übergeben werden kann. Wenn eine nicht übergeben wird, wird die aktuelle Kultur verwendet. Dies gibt ihm maximale Flexibilität und Wiederverwendung.
/// <summary>
/// Gets the date of the first day of the week for the date.
/// </summary>
/// <param name="date">The date to be used</param>
/// <param name="cultureInfo">If none is provided, the current culture is used</param>
/// <returns>The date of the beggining of the week based on the culture specifed</returns>
public static DateTime StartOfWeek(this DateTime date, CultureInfo cultureInfo=null) =>
date.AddDays(-1 * (7 + (date.DayOfWeek - (cultureInfo??CultureInfo.CurrentCulture).DateTimeFormat.FirstDayOfWeek)) % 7).Date;
Anwendungsbeispiel:
public static void TestFirstDayOfWeekExtension() {
DateTime date = DateTime.Now;
foreach(System.Globalization.CultureInfo culture in CultureInfo.GetCultures(CultureTypes.UserCustomCulture | CultureTypes.SpecificCultures)) {
Console.WriteLine($"{culture.EnglishName}: {date.ToShortDateString()} First Day of week: {date.StartOfWeek(culture).ToShortDateString()}");
}
}
Wenn Sie Samstag oder Sonntag oder einen Wochentag möchten, aber die aktuelle Woche (Sa-So) nicht überschreiten, habe ich Sie mit diesem Code abgedeckt.
public static DateTime GetDateInCurrentWeek(this DateTime date, DayOfWeek day)
{
var temp = date;
var limit = (int)date.DayOfWeek;
var returnDate = DateTime.MinValue;
if (date.DayOfWeek == day) return date;
for (int i = limit; i < 6; i++)
{
temp = temp.AddDays(1);
if (day == temp.DayOfWeek)
{
returnDate = temp;
break;
}
}
if (returnDate == DateTime.MinValue)
{
for (int i = limit; i > -1; i++)
{
date = date.AddDays(-1);
if (day == date.DayOfWeek)
{
returnDate = date;
break;
}
}
}
return returnDate;
}
Wir mögen Einzeiler: Ermitteln Sie die Differenz zwischen dem ersten Wochentag der aktuellen Kultur und dem aktuellen Tag und subtrahieren Sie dann die Anzahl der Tage vom aktuellen Tag
var weekStartDate = DateTime.Now.AddDays(-((int)now.DayOfWeek - (int)DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek));
Verwenden Sie nach Kompilieren dieser Antwort die folgende Methode, um das Datum für einen beliebigen Wochentag zu ermitteln:
public static DateTime GetDayOfWeek(this DateTime dt, DayOfWeek day)
{
int diff = (7 + (dt.DayOfWeek - DayOfWeek.Monday)) % 7;
var monday = dt.AddDays(-1 * diff).Date;
switch (day)
{
case DayOfWeek.Tuesday:
return monday.AddDays(1).Date;
case DayOfWeek.Wednesday:
return monday.AddDays(2).Date;
case DayOfWeek.Thursday:
return monday.AddDays(3).Date;
case DayOfWeek.Friday:
return monday.AddDays(4).Date;
case DayOfWeek.Saturday:
return monday.AddDays(5).Date;
case DayOfWeek.Sunday:
return monday.AddDays(6).Date;
}
return monday;
}
Versuchen Sie, eine Funktion zu erstellen, die Rekursion verwendet. Ihr DateTime-Objekt ist eine Eingabe und die Funktion gibt ein neues DateTime-Objekt zurück, das für den Wochenanfang steht.
DateTime WeekBeginning(DateTime input)
{
do
{
if (input.DayOfWeek.ToString() == "Monday")
return input;
else
return WeekBeginning(input.AddDays(-1));
} while (input.DayOfWeek.ToString() == "Monday");
}
Wenn Sie auf diese Weise berechnen, können Sie auswählen, welcher Wochentag den Beginn einer neuen Woche anzeigt (in dem Beispiel, das ich Montag gewählt habe).
Beachten Sie, dass diese Berechnung für einen Tag, der ein Montag ist, den aktuellen Montag und nicht den vorherigen ergibt .
//Replace with whatever input date you want
DateTime inputDate = DateTime.Now;
//For this example, weeks start on Monday
int startOfWeek = (int)DayOfWeek.Monday;
//Calculate the number of days it has been since the start of the week
int daysSinceStartOfWeek = ((int)inputDate.DayOfWeek + 7 - startOfWeek) % 7;
DateTime previousStartOfWeek = inputDate.AddDays(-daysSinceStartOfWeek);
int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;