Jak znaleźć początek tygodnia (zarówno w niedzielę, jak i poniedziałek), znając tylko aktualny czas w C #?
Coś jak:
DateTime.Now.StartWeek(Monday);
Użyj metody rozszerzenia. Są odpowiedzią na wszystko, wiesz! ;)
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;
}
}
Które mogą być używane w następujący sposób:
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);
int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;
dt
jest UTC i jest już początek tygodnia, np2012-09-02 16:00:00Z
który jestMon, 03 Sep 2012 00:00:00
w czasie lokalnym. Więc musi przeliczyćdt
na czas lokalny lub zrobić coś mądrzejszego. Musi również zwrócić wynik jako UTC, jeśli dane wejściowe to UTC.DateTime.Parse("2012-09-02 16:00:00Z")
zwraca ekwiwalent czasu lokalnego, a ta metoda poprawnie zwraca ten sam czas, co czas lokalny. Jeśli użyjeszDateTime.Parse("2012-09-02 16:00:00Z").ToUniversalTime()
do jawnego przekroczenia czasu UTC, ta metoda poprawnie zwróci 6 dni, 16 godzin wcześniej, jako czas UTC. Działa dokładnie tak, jak się spodziewałam.dt
. Użyłemint diff = dt.Date.DayOfWeek - startOfWeek;
Najszybszym sposobem na wymyślenie tego jest:
Jeśli chcesz, aby jakikolwiek inny dzień tygodnia był Twoją datą początkową, wystarczy dodać wartość DayOfWeek na końcu
źródło
Trochę bardziej szczegółowy i świadomy kultury:
źródło
CultureInfo.CurrentCulture
zamiast ściągać ją z wątku w ten sposób. Wydaje się to dziwnym sposobem na dostęp do niego.Now
dwukrotne wywołanie nieruchomości. Jeśli aktualny czas upłynie 24:00 (lub 12:00 północy) między dwoma połączeniami, data ulegnie zmianie.Korzystając z płynnego DateTime :
źródło
public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
Brzydkie, ale przynajmniej daje właściwe daty
Z początkiem tygodnia ustawionym przez system:
Bez:
źródło
Połączmy odpowiedź bezpieczną dla kultury i odpowiedź metodą rozszerzenia:
źródło
dt
zamiastDateTime.Today
, aby zawinąć matematykę w(offset + 7) % 7
celu zapewnienia ujemnego przesunięcia, aby użyć przeciążenia metody jednoparametrowej, która przekazuje argumenty bieżącej kulturyFirstDayOfWeek
jakostartOfWeek
argument, i ewentualnie (w zależności od specyfikacji) wymusić zero przesunięcia do 7-dniowego przesunięcia, aby „ostatni wtorek” nie powrócił dzisiaj, jeśli jest już wtorek.To dałoby ci poprzednią niedzielę (tak myślę):
źródło
Może to być trochę włamanie, ale możesz rzucić właściwość .DayOfWeek na int (jest to wyliczenie, a ponieważ nie zmieniono podstawowego typu danych, domyślnie jest to int) i użyć tego, aby określić poprzedni początek tygodnia .
Wydaje się, że tydzień określony w wyliczeniu DayOfWeek rozpoczyna się w niedzielę, więc jeśli odejmiemy 1 od tej wartości, będzie to równa liczbie dni, w które poniedziałek przypada przed bieżącą datą. Musimy również zmapować niedzielę (0) na wartość równą 7, więc biorąc pod uwagę 1 - 7 = -6 niedziela zmapuje do poprzedniego poniedziałku: -
Kod z poprzedniej niedzieli jest prostszy, ponieważ nie musimy dokonywać tej korekty: -
źródło
Na poniedziałek
Na niedzielę
źródło
źródło
Łącząc to wszystko z Globalizacją i pozwalając określić pierwszy dzień tygodnia w ramach naszego zaproszenia
źródło
źródło
To da ci północ w pierwszą niedzielę tygodnia:
To daje pierwszy poniedziałek o północy:
źródło
spróbuj tego w c #. Za pomocą tego kodu możesz uzyskać zarówno pierwszą datę, jak i ostatnią datę danego tygodnia. Tutaj niedziela jest pierwszym dniem, a sobota jest ostatnim dniem, ale możesz ustawić oba dni zgodnie z własną kulturą
źródło
Próbowałem kilka, ale nie rozwiązałem problemu z tygodniem rozpoczynającym się w poniedziałek, co dało mi przyszły poniedziałek w niedzielę. Więc trochę go zmodyfikowałem i działałem z tym kodem:
źródło
dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
Krok 1: Utwórz klasę statyczną
Krok 2: Użyj tej klasy, aby uzyskać początek i koniec dnia tygodnia
źródło
(6 - (dt.DayOfWeek - startOfWeek)) % 7
w stosunku do testów jednostkowych, które napisałem.Następująca metoda powinna zwrócić wybraną datę i godzinę. Przekaż prawdę, ponieważ niedziela jest pierwszym dniem tygodnia, fałsz w poniedziałek:
źródło
Dzięki za przykłady. Musiałem zawsze używać „CurrentCulture” pierwszego dnia tygodnia, a dla tablicy musiałem znać dokładną liczbę dni… więc oto moje pierwsze rozszerzenia:
źródło
Wydaje się, że nikt jeszcze nie odpowiedział na to poprawnie. Wkleję tutaj moje rozwiązanie na wypadek, gdyby ktoś go potrzebował. Poniższy kod działa niezależnie od tego, czy pierwszy dzień tygodnia to poniedziałek, niedziela czy coś innego.
źródło
Modulo w C # działa źle dla -1mod7 (powinno być 6, c # zwraca -1), więc ... "oneliner" rozwiązanie tego będzie wyglądać tak :)
źródło
To samo na koniec tygodnia (w stylu @Compile To jest odpowiedź):
źródło
Możesz użyć doskonałej biblioteki Umbrella :
Jednak oni nie wydają się być przechowywane w poniedziałek jako pierwszy dzień tygodnia (patrz właściwość
nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn
), tak, że poprzednie rozwiązanie zlokalizowana jest nieco lepiej. Niefortunny.Edycja : patrząc bliżej na pytanie, wygląda na to, że Parasol też może na to zadziałać:
Chociaż warto zauważyć, że jeśli poprosisz o poprzedni poniedziałek w poniedziałek, da ci to siedem dni wstecz. Ale jest to również prawdą, jeśli używasz
BeginningOfWeek
, co wydaje się błędem :(.źródło
Zwróci zarówno początek tygodnia, jak i koniec tygodnia:
Na moim blogu ZamirsBlog zamieściłem pełny kod do obliczania początku / końca tygodnia, miesiąca, kwartału i roku
źródło
źródło
Oto kombinacja kilku odpowiedzi. Wykorzystuje metodę rozszerzenia, która umożliwia przekazanie kultury, jeśli nie zostanie przekazana, używana jest bieżąca kultura. Zapewni to maksymalną elastyczność i ponowne użycie.
Przykładowe użycie:
źródło
jeśli chcesz w sobotę lub niedzielę lub w dowolny dzień tygodnia, ale nie dłużej niż w bieżącym tygodniu (sob. – niedz.), obdarzyłem cię tym kodem.
źródło
Lubimy one-liner: znajdź różnicę między pierwszym dniem tygodnia bieżącej kultury a bieżącym dniem, a następnie odejmij liczbę dni od bieżącego dnia
źródło
Kontynuując kompilowanie tej odpowiedzi, użyj następującej metody, aby uzyskać datę dla dowolnego dnia tygodnia:
źródło
Spróbuj utworzyć funkcję korzystającą z rekurencji. Twój obiekt DateTime jest wejściem, a funkcja zwraca nowy obiekt DateTime, który oznacza początek tygodnia.
źródło
Obliczenie w ten sposób pozwala wybrać, który dzień tygodnia wskazuje początek nowego tygodnia (w przykładzie, który wybrałem w poniedziałek).
Pamiętaj, że wykonanie tego obliczenia dla dnia, który jest w poniedziałek, da bieżący poniedziałek, a nie poprzedni.
źródło