Jak mogę uzyskać DateTime na początek tygodnia?


469

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);

Odpowiedzi:


746

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);

15
Możesz to uprościć w następujący sposób: int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;
Troy

13
Troja, nie wierzę, że Twój kod działa, jeśli podana data to niedziela, a początek tygodnia to poniedziałek. Wróci (niedziela + 1) zamiast (niedziela - 6)
Aaron Hoffman

1
To nie działa, jeśli dtjest UTC i jest już początek tygodnia, np 2012-09-02 16:00:00Zktóry jest Mon, 03 Sep 2012 00:00:00w czasie lokalnym. Więc musi przeliczyć dtna czas lokalny lub zrobić coś mądrzejszego. Musi również zwrócić wynik jako UTC, jeśli dane wejściowe to UTC.
wiersz 1

1
@ wiersz1 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żyjesz DateTime.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.
Rawling,

1
Czasem byłby to dla mnie jeden dzień. To zadziałało dla mnie po usunięciu komponentu czasu dt. Użyłemint diff = dt.Date.DayOfWeek - startOfWeek;
Vincent Saelzler

80

Najszybszym sposobem na wymyślenie tego jest:

var sunday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek);

Jeśli chcesz, aby jakikolwiek inny dzień tygodnia był Twoją datą początkową, wystarczy dodać wartość DayOfWeek na końcu

var monday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Monday);

var tuesday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Tuesday); 

2
najprostsze odpowiedzi są najlepsze, ta działała dobrze, ale kultura zależała
Cerveser

7
Na Łotwie tydzień zaczyna się w poniedziałek ... Właściwie zawsze zastanawiam się, jak tydzień może zacząć się w niedzielę ... wydaje mi się niewygodny ..;)
0xDEAD BEEF

To rozwiązanie jest dobre. Ponadto możesz rozpocząć tydzień każdego dnia, dodając DayOfWeek, od którego chcesz zacząć. var niedziela = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek); var poniedziałek = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek + (int) DayOfWeek.Monday);
Loligans,

7
Ten dodany kod nie działa w sytuacji opisanej przez Threezol. Jeśli chcesz, aby początkiem tygodnia był poniedziałek, w niedzielę obliczenia podadzą przyszły poniedziałek, a nie poprzedni.
Giovanni B

4
Tak .. W niedzielę daje następny Modnay .. nie poprzedni: P
Ajay Aradhya

64

Trochę bardziej szczegółowy i świadomy kultury:

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;

4
wystąpił błąd z tym: dzisiaj = NIEDZIELA; fdow = PONIEDZIAŁEK; (dzisiaj - fdow) == -1; DateTime.Now.AddDays (- (- 1)). Date == DateTime.Now.AddDays (+1) .Date; 01-02-2010! = 25-01-2010 !!
balexandre

3
Jeśli spróbujesz tego w niedzielę, to w zasadzie robi AddDays (0-1) dla en-GB. Potrzebuje więc oświadczenia @ Sarcastic, jeśli
S Chris

3
Możesz również pobrać aktualną kulturę, CultureInfo.CurrentCulturezamiast ściągać ją z wątku w ten sposób. Wydaje się to dziwnym sposobem na dostęp do niego.
Hank,

7
Kolejny problem: niebezpieczne jest Nowdwukrotne 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.
Jeppe Stig Nielsen

1
Ta odpowiedź faktycznie brzmi: „w bieżącym tygodniu .NET (zaczynającym się w niedzielę i kończącym się w sobotę, zgodnie z numeracją wyliczenia DayOfWeek), znajdź dzień tygodnia .NET, który jest pierwszym w tygodniu w obecnej kulturze ". Prawdopodobnie nie tego chcesz.
Mathieu Renda,

36

Korzystając z płynnego DateTime :

var monday = DateTime.Now.Previous(DayOfWeek.Monday);
var sunday = DateTime.Now.Previous(DayOfWeek.Sunday);

29
Nienawidzę brać na siebie zależności tylko z tego powodu. Wydaje się, że przychodzi na myśl „Poznaj swoje zależności i zabij je”. :)
Esteban Araya

7
Czy ktoś zauważył JAK DZIAŁA „Biegły”? Spójrz tylko na kod. Używa pętli do ... while. Nie chcę nazywać go imionami, ale jeśli zdecyduję się to zrobić, nie będzie to przyjemne. public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
nsimeonov

10
@nsimeonov jest open source. prosimy o lepszą implementację niż rzucanie kamieniami.
Simon

12
Tak, jakbym miał cały czas na świecie, aby naprawić każdy błąd w każdym oprogramowaniu open source na świecie ...
nsimeonov

4
Musiałem skomentować, ponieważ bardzo się śmiałem ze skargi dotyczącej używania pętli „do ... while”! Wesoły! Nigdy wcześniej nie słyszałem, aby inny programista drżał z powodu pętli. Chciałbym zobaczyć twarz tego klauna, kiedy / jeśli kiedykolwiek zda sobie sprawę z tego, w co właściwie się składa.
Josh Stodola,

22

Brzydkie, ale przynajmniej daje właściwe daty

Z początkiem tygodnia ustawionym przez system:

    public static DateTime FirstDateInWeek(this DateTime dt)
    {
        while (dt.DayOfWeek != System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
            dt = dt.AddDays(-1);
        return dt;
    }

Bez:

    public static DateTime FirstDateInWeek(this DateTime dt, DayOfWeek weekStartDay)
    {
        while (dt.DayOfWeek != weekStartDay)
            dt = dt.AddDays(-1);
        return dt;
    }

3
To naprawdę zasługuje na więcej głosów za swoją prostotę i czytelność.
ProfK

Ten zasób również pomógł: markb.uk/... (Jeśli chcesz uzyskać pierwszy / ostatni dzień tygodnia lub miesiąca).
FranzHuber23

13

Połączmy odpowiedź bezpieczną dla kultury i odpowiedź metodą rozszerzenia:

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));
    }
}

12
ani dt, ani startOfWeek nie jest używany w twojej funkcji, chyba pierwszy powinien być użyty zamiast DateTime.
Dzisiaj

2
Kontekst tego pytania polega na tym, że dodatkowa właściwość ma być wyłączona z Datetime w taki sam sposób, jak .Today lub .Now. Zgadzam się, że to niezręczne, ale o to poproszono.
Joel Coehoorn

7
Wiem, że to stara odpowiedź, ale jest błędna na wielu poziomach; oprócz całkowitego ignorowania argumentów metody, matematyka spowoduje, że w wielu przypadkach wybierze przyszłą datę. Powinno to być napisane, aby użyć dtzamiast DateTime.Today, aby zawinąć matematykę w (offset + 7) % 7celu zapewnienia ujemnego przesunięcia, aby użyć przeciążenia metody jednoparametrowej, która przekazuje argumenty bieżącej kultury FirstDayOfWeekjako startOfWeekargument, 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.
Aaronaught

10

To dałoby ci poprzednią niedzielę (tak myślę):

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, 0, 0, 0);

9

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: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
DateTime startOfWeek = now.AddDays(1 - (int)now.DayOfWeek);

Kod z poprzedniej niedzieli jest prostszy, ponieważ nie musimy dokonywać tej korekty: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
DateTime startOfWeek = now.AddDays(-(int)now.DayOfWeek);

9

Na poniedziałek

DateTime startAtMonday = DateTime.Now.AddDays(DayOfWeek.Monday - DateTime.Now.DayOfWeek);

Na niedzielę

DateTime startAtSunday = DateTime.Now.AddDays(DayOfWeek.Sunday- DateTime.Now.DayOfWeek);

1
Miałem inną potrzebę aplikacji, ale wykorzystałem to, aby zacząć. Podoba mi się, ponieważ jest najprostszy, bez rzutowania - zachowując operacje w tym samym / odpowiednim typie.
qxotk

1
To nie działa, gdy dzień jest w niedzielę. Daje następny poniedziałek, a nie początek bieżącego tygodnia.
Grant

Czy skopiowałeś także niedzielę lub poniedziałek. Mam 2 odpowiedzi Jedna, jeśli chcesz na poniedziałek, i 2, jeśli chcesz na niedzielę ... Właśnie ją przetestowałem i działa mi dobrze. DateTime.Now.DayOfWeek; Niedziela i wynik DateTime.Now.AddDays (DayOfWeek.Sunday - DateTime.Now.DayOfWeek); {10/11/2019 4:14:55 μμ} Data: {10/11/2019 12:00:00 πμ} Dzień: 10 DayOfWeek: Sunday DayOfYear: 314 Hour: 16 Rodzaj: Local Millisecond: 172 Minute: 14 Month : 11 Second: 55 Ticks: 637089992951723516 TimeOfDay: {16: 14: 55.1723516} Rok: 2019
George Stavrou

@GrantJ Jaką linię podjąłeś ??? Właśnie przetestowałem i działa dobrze.
George Stavrou

Wypróbowałem pierwszy, zastępując swój DateTime. Teraz DateTime reprezentujący niedzielę 10 listopada 2019 r. Powinien dać poniedziałek 4 listopada 2019 r., Ale daje poniedziałek 11 listopada 2019 r. Ustawiłem
Grant J

5
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();
        }
    }
}

3
Po pierwsze, witamy w społeczności :) Istnieje już kilka wysokiej jakości odpowiedzi na to pytanie, z których większość została opublikowana siedem lat temu, kiedy pytanie zostało zadane. Chociaż warto spróbować odpowiedzieć na proste pytania, takie jak to, aby rozwinąć swoje umiejętności programistyczne, opublikowanie tej odpowiedzi w jej obecnym stanie nic nie dodaje do pytania. Jeśli w twojej odpowiedzi jest coś nowego, weź kilka zdań, aby wyjaśnić, jak się różni i dlaczego to poprawia.
MTCoster,

4

Łącząc to wszystko z Globalizacją i pozwalając określić pierwszy dzień tygodnia w ramach naszego zaproszenia

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;

}

4
var now = System.DateTime.Now;

var result = now.AddDays(-((now.DayOfWeek - System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 7) % 7)).Date;

2

To da ci północ w pierwszą niedzielę tygodnia:

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, t.Hour, t.Minute, t.Second);

To daje pierwszy poniedziałek o północy:

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek - 1, t.Hour, t.Minute, t.Second);

2

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ą

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;
}

2

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:

int delta = DayOfWeek.Monday - DateTime.Now.DayOfWeek;
DateTime monday = DateTime.Now.AddDays(delta == 1 ? -6 : delta);
return monday;

Wygląda na to, że problem „nadchodzącego poniedziałku” zależy od kultury (patrz również odpowiedź Erica i komentarz Cervesera). Jeśli jednak nie musisz brać pod uwagę niedziel (jak w przypadku zwykłych spotkań biznesowych), twoja formuła może uproszczone:dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
Damian Vogel

2

Krok 1: Utwórz klasę statyczną

  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;
    }
}

Krok 2: Użyj tej klasy, aby uzyskać początek i koniec dnia tygodnia

 DateTime dt =TIMEE.StartOfWeek(DateTime.Now ,DayOfWeek.Monday);
        DateTime dt1 = TIMEE.EndOfWeek(DateTime.Now, DayOfWeek.Sunday);

Wymagany koniec tygodnia (6 - (dt.DayOfWeek - startOfWeek)) % 7w stosunku do testów jednostkowych, które napisałem.
mlhDev,

1

Następująca metoda powinna zwrócić wybraną datę i godzinę. Przekaż prawdę, ponieważ niedziela jest pierwszym dniem tygodnia, fałsz w poniedziałek:

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);
}

1

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:

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
    }
}

1

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.

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());
  }
}

1

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 :)

private static DateTime GetFirstDayOfWeek(DateTime date)
    {
        return date.AddDays(-(((int)date.DayOfWeek - 1) - (int)Math.Floor((double)((int)date.DayOfWeek - 1) / 7) * 7));
    }

1

To samo na koniec tygodnia (w stylu @Compile To jest odpowiedź):

    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) { };
    }

0

Możesz użyć doskonałej biblioteki Umbrella :

using nVentive.Umbrella.Extensions.Calendar;
DateTime beginning = DateTime.Now.BeginningOfWeek();

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ć:

// Or DateTime.Now.PreviousDay(DayOfWeek.Monday)
DateTime monday = DateTime.Now.PreviousMonday(); 
DateTime sunday = DateTime.Now.PreviousSunday();

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 :(.


0

Zwróci zarówno początek tygodnia, jak i koniec tygodnia:

    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;

    }

Na moim blogu ZamirsBlog zamieściłem pełny kod do obliczania początku / końca tygodnia, miesiąca, kwartału i roku


0
    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();
            }
        }
    } 

Czy możesz rozszerzyć swoją odpowiedź, aby zawierała wyjaśnienie swojego kodu? Pomaga czytelnikowi bardziej niż myślisz.
gunr2171

Korzystanie z rekurencji jest bardzo słabą implementacją. To, że możesz użyć rekurencji, nie oznacza, że ​​powinieneś. Byłby wolniejszy i wymagałby więcej pamięci niż inne przedstawione tutaj rozwiązania.
mikecamimo

0

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.

/// <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;

Przykładowe użycie:

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()}");
        }
    }

0

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.

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;
}

0

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

var weekStartDate = DateTime.Now.AddDays(-((int)now.DayOfWeek - (int)DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek));

0

Kontynuując kompilowanie tej odpowiedzi, użyj następującej metody, aby uzyskać datę dla dowolnego dnia tygodnia:

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;
}

0

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.

    DateTime WeekBeginning(DateTime input)
    {
        do
        {
            if (input.DayOfWeek.ToString() == "Monday")
                return input;
            else
                return WeekBeginning(input.AddDays(-1));
        } while (input.DayOfWeek.ToString() == "Monday");
    }

Chociaż ten kod może rozwiązać pytanie, w tym wyjaśnienie, w jaki sposób i dlaczego to rozwiązuje problem, naprawdę pomógłby poprawić jakość twojego postu i prawdopodobnie doprowadziłby do większej liczby głosów. Pamiętaj, że odpowiadasz na pytanie dla czytelników w przyszłości, nie tylko dla osoby zadającej teraz pytanie. Proszę edytować swoje odpowiedzi, aby dodać wyjaśnień i dać wskazówkę co zastosować ograniczenia i założenia.
David Buck

0

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.

//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);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.