Come posso ottenere il DateTime per l'inizio della settimana?


469

Come faccio a trovare l'inizio della settimana (sia domenica che lunedì) conoscendo l'ora corrente in C #?

Qualcosa di simile a:

DateTime.Now.StartWeek(Monday);

Risposte:


746

Utilizzare un metodo di estensione. Sono la risposta a tutto, lo sai! ;)

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

Quale può essere usato come segue:

DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);

15
Puoi semplificarlo come segue: int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;
Troia,

13
Troia, non credo che il tuo codice funzioni se la data indicata è domenica e l'inizio della settimana è lunedì. Tornerà (domenica + 1) anziché (domenica - 6)
Aaron Hoffman il

1
Questo non funziona se dtè UTC ed è già l'inizio della settimana, ad es. 2012-09-02 16:00:00ZChe è Mon, 03 Sep 2012 00:00:00in ora locale. Quindi deve convertirsi dtin ora locale o fare qualcosa di un po 'più intelligente. Dovrebbe inoltre restituire il risultato come UTC se l'input fosse UTC.
row1,

1
@ row1 DateTime.Parse("2012-09-02 16:00:00Z")restituisce l'equivalente dell'ora locale e questo metodo restituisce correttamente la stessa ora, come l'ora locale. Se si utilizza DateTime.Parse("2012-09-02 16:00:00Z").ToUniversalTime()per passare esplicitamente l'ora UTC, questo metodo restituisce correttamente 6 giorni, 16 ore prima, come ora UTC. Funziona esattamente come mi aspettavo.
Rawling,

1
A volte questo sarebbe spento per un giorno per me. Ha funzionato per me una volta che ho rimosso la componente temporale dt. Ho usatoint diff = dt.Date.DayOfWeek - startOfWeek;
Vincent Saelzler

80

Il modo più veloce che posso trovare è:

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

Se desideri che un altro giorno della settimana sia la tua data di inizio, tutto ciò che devi fare è aggiungere il valore DayOfWeek alla fine

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
le risposte più semplici sono le migliori, questa ha funzionato bene, ma la cultura è dipesa
Cerveser

7
In Lettonia la settimana inizia a lunedì .. In realtà .. Mi chiedo sempre come può iniziare una settimana domenica .. mi sembra imbarazzante ..;)
0xDEAD BEEF

Questa soluzione è buona Inoltre, puoi iniziare la settimana in qualsiasi giorno aggiungendo il DayOfWeek che desideri iniziare. var domenica = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek); var monday = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek + (int) DayOfWeek.Monday);
Loligans,

7
Questo codice aggiunto non funziona per la situazione descritta da Threezol. Se vuoi che l'inizio della settimana sia il lunedì, la domenica il calcolo ti dà il prossimo lunedì, non il precedente.
Giovanni B,

4
Sì .. Per domenica, si dà il prossimo Modnay .. non il precedente: P
Ajay Aradhya

64

Un po 'più prolisso e attento alla cultura:

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
ho ricevuto un errore con questo: oggi = DOMENICA; fdow = LUNEDÌ; (oggi - fdow) == -1; DateTime.Now.AddDays (- (- 1)). Date == DateTime.Now.AddDays (+1) .Date; 01-02-2010! = 25-01-2010 !!
balexandre,

3
Se lo provi una domenica, allora fondamentalmente sta facendo AddDays (0 - 1) per en-GB. Quindi ha bisogno dell'istruzione if di @ Sarcastic
Chris S,

3
Puoi anche ottenere la cultura corrente usando CultureInfo.CurrentCultureinvece di toglierla dal thread in quel modo. Sembra un modo strano di accedervi.
Hank

7
Un altro problema: è pericoloso chiamare la Nowproprietà due volte. Se l'ora corrente passa tra le due chiamate 24:00 (o 12:00 mezzanotte), la data sarà cambiata.
Jeppe Stig Nielsen,

1
Ciò che questa risposta effettivamente fa è questo: "all'interno della settimana .NET corrente (che inizia di domenica e termina di sabato, secondo la numerazione dell'enumerazione DayOfWeek), trova il giorno della settimana .NET che è il primo della settimana nella cultura attuale ". Questo probabilmente non è quello che vuoi.
Mathieu Renda,

36

Utilizzando DateTime fluente :

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

29
Odierei assumermi una dipendenza solo per questo. "Conoscere le tue dipendenze e ucciderle" sembra venire in mente. :)
Esteban Araya,

7
Qualcuno ha notato come funziona "Fluent"? Dai un'occhiata al codice. Sta usando un do ... while loop. Non voglio chiamarlo nomi, ma se decido di farlo non sarà piacevole. public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
nsimeonov,

10
@nsimeonov è open source. non esitate a fornire una migliore implementazione piuttosto che lanciare pietre.
Simon,

12
Sì, come se avessi tutto il tempo per riparare ogni singolo bug in ogni software open source del mondo ...
nsimeonov

4
Ho dovuto commentare perché ho ricevuto una risata enorme dalla lamentela sull'uso di un ciclo "do ... while"! Divertente! Non ho mai sentito un altro programmatore rabbrividire per un loop prima. Mi piacerebbe vedere la faccia di questo pagliaccio quando / se mai realizzerà in cosa si compila il suo codice.
Josh Stodola,

22

Brutto ma almeno restituisce le date giuste

Con l'inizio della settimana impostato dal sistema:

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

Senza:

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

3
Questo merita davvero più voti per la sua semplicità e leggibilità.
ProfK,

Anche questa risorsa ha aiutato: markb.uk/… (se vuoi ottenere il primo / ultimo giorno di una settimana o mese).
FranzHuber23,

13

Uniamo la risposta sicura per la cultura e la risposta del metodo di estensione:

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
né dt né startOfWeek sono utilizzati all'interno della tua funzione, immagino che il primo dovrebbe essere usato al posto di DateTime.Today
hultqvist

2
Il contesto della domanda vuole che una proprietà aggiuntiva venga utilizzata al di fuori di Datetime allo stesso modo di .Today o .Now. Sono d'accordo che sia imbarazzante, ma è quello che è stato chiesto.
Joel Coehoorn,

7
So che questa è una vecchia risposta, ma è sbagliata su così tanti livelli; oltre a ignorare totalmente gli argomenti del metodo, la matematica farà sì che scelga una data futura in molti casi. Questo avrebbe dovuto essere scritto per usare dtinvece di DateTime.Today, per avvolgere la matematica in un (offset + 7) % 7modo per garantire un offset negativo, per usare un sovraccarico del metodo a parametro singolo che passa FirstDayOfWeekl' startOfWeekargomento della cultura corrente come argomento, e possibilmente (a seconda delle specifiche) per forzare un zero offset a un offset di 7 giorni, in modo che "martedì scorso" non ritorni oggi se è già martedì.
Aaronaught il

10

Questo ti darebbe la domenica precedente (penso):

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

9

Questo potrebbe essere un po 'un trucco, ma puoi lanciare la proprietà .DayOfWeek su un int (è un enum e dal momento che non ha cambiato il suo tipo di dati sottostante è impostato come predefinito) e usarlo per determinare l'inizio della settimana precedente .

Sembra che la settimana specificata nell'enum DayOfWeek abbia inizio domenica, quindi se sottraggiamo 1 da questo valore sarà uguale a quanti giorni è il lunedì prima della data corrente. Dobbiamo anche mappare la domenica (0) in modo che sia uguale a 7, quindi dato 1 - 7 = -6 la domenica verrà mappata al lunedì precedente: -

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

Il codice per la domenica precedente è più semplice in quanto non è necessario apportare questa modifica: -

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

9

Per lunedì

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

Per domenica

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

1
Avevo bisogno di un'applicazione diversa, tuttavia l'ho usato per iniziare. Mi piace perché è il più semplice, senza alcun casting - mantenendo le operazioni negli stessi / appropriati tipi.
qxotk,

1
Questo non funziona quando il giorno è domenica. Dà il lunedì successivo, non l'inizio della settimana corrente.
Concedi il

Hai anche copiato la domenica o il lunedì. Ho 2 risposte Uno se vuoi per lunedì e 2 se vuoi per domenica ..... L'ho appena provato e funziona bene per me. DateTime.Now.DayOfWeek; Domenica e risultato DateTime.Now.AddDays (DayOfWeek.Sunday - DateTime.Now.DayOfWeek); {10/11/2019 4:14:55 μμ} Data: {10/11/2019 12:00:00 πμ} Giorno: 10 giorni di settimana: domenica giorno di anno: 314 ora: 16 tipo: millisecondo locale: 172 minuti: 14 mesi : 11 Secondo: 55 Tick: 637089992951723516 TimeOfDay: {16: 14: 55.1723516} Anno: 2019
George Stavrou

@GrantJ Che linea hai preso ??? Ho appena testato e funziona benissimo.
George Stavrou,

Ho provato il primo, sostituendo il tuo DateTime.Ora con un DateTime che rappresenta domenica 10 novembre 2019. Dovrebbe essere lunedì 4 novembre 2019 ma lunedì 11 novembre 2019. Ho impostato un violino dimostrandolo qui: dotnetfiddle.net/ Jw3ZiO
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
Prima di tutto, benvenuto nella community :) Esistono già diverse risposte di alta qualità a questa domanda, la maggior parte delle quali sono state pubblicate sette anni fa quando è stata posta la domanda. Mentre può essere un esercizio utile tentare di rispondere a domande semplici come questa al fine di migliorare le tue capacità di programmazione, pubblicare questa risposta nel suo stato attuale non aggiunge nulla alla domanda. Se c'è qualcosa di nuovo nella tua risposta, ti preghiamo di prendere un paio di frasi per spiegare come è diverso e perché ciò lo rende migliore.
MTCoster,

4

Mettendo tutto insieme, con la globalizzazione e consentendo di specificare il primo giorno della settimana come parte della chiamata che abbiamo

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

Questo ti darebbe mezzanotte la prima domenica della settimana:

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

Questo ti dà il primo lunedì a mezzanotte:

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

2

prova con questo in c # .Con questo codice puoi ottenere sia il primo che l'ultimo giorno di una determinata settimana. Qui la domenica è il primo giorno e il sabato è l'ultimo giorno ma puoi impostare entrambi i giorni in base alla tua cultura

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

Ho provato diversi ma non ho risolto il problema con una settimana a partire da un lunedì, risultando nel darmi il prossimo lunedì di domenica. Quindi l'ho modificato un po 'e l'ho fatto funzionare con questo codice:

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

Sembra che il problema del "prossimo lunedì" dipenda dalla cultura (vedi anche la risposta di Eric e il commento di Cerveser). Tuttavia, se non hai bisogno di prendere in considerazione la domenica (come con i soliti appuntamenti di lavoro) la tua formula può semplificato:dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
Damian Vogel,

2

Passaggio 1: creare una classe statica

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

Passaggio 2: utilizzare questa classe per ottenere sia il giorno di inizio che di fine della settimana

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

Fine della settimana richiesto (6 - (dt.DayOfWeek - startOfWeek)) % 7per me contro i test unitari che ho scritto.
mlhDev

1

Il seguente metodo dovrebbe restituire il DateTime desiderato. Passa vero per domenica essendo il primo giorno della settimana, falso per lunedì:

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

Grazie per gli esempi Avevo bisogno di usare sempre "CurrentCulture" il primo giorno della settimana e per un array avevo bisogno di conoscere l'esatto Daynumber .. quindi ecco le mie prime estensioni:

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

Nessuno sembra aver ancora risposto correttamente. Incollerò la mia soluzione qui nel caso qualcuno ne abbia bisogno. Il seguente codice funziona indipendentemente dal fatto che il primo giorno della settimana sia un lunedì o una domenica o qualcos'altro.

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 in C # funziona male per -1mod7 (dovrebbe essere 6, c # restituisce -1) quindi ... la soluzione "oneliner" a questo apparirà così :)

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

1

Lo stesso per la fine della settimana (nello stile di @Compile Questa è la risposta):

    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

Potresti usare l'eccellente libreria Umbrella :

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

Tuttavia, essi non sembrano aver memorizzato Lunedi come il primo giorno della settimana (vedere la proprietà nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn), in modo che la soluzione localizzata precedente è un po 'meglio. Sfortunato.

Modifica : guardando più da vicino alla domanda, sembra che anche Umbrella potrebbe funzionare anche per quello:

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

Anche se vale la pena notare che se chiedi il lunedì precedente di lunedì, ti restituirà sette giorni indietro. Ma questo vale anche se lo usi BeginningOfWeek, che sembra un bug :(.


0

Ciò restituirà le date di inizio della settimana e di fine della settimana:

    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;

    }

Ho pubblicato il codice completo per il calcolo dell'inizio / fine della settimana, mese, trimestre e anno sul mio blog ZamirsBlog


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

Puoi espandere la tua risposta per includere una spiegazione del tuo codice? Aiuta il lettore più di quanto si possa pensare.
gunr2171,

L'uso della ricorsione è un'implementazione molto scarsa. Solo perché potresti usare le ricorsioni non significa che dovresti. Sarebbe più lento e richiede più memoria rispetto ad altre soluzioni fornite qui.
mikecamimo,

0

Ecco una combinazione di alcune delle risposte. Utilizza un metodo di estensione che consente di passare la cultura, se non viene passata, viene utilizzata la cultura corrente. Ciò garantirà la massima flessibilità e riutilizzo.

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

Esempio di utilizzo:

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

se vuoi sabato o domenica o qualsiasi giorno della settimana ma non superare la settimana corrente (sabato-domenica), ti copro con questo codice.

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

Ci piace il one-liner: ottieni la differenza tra il primo giorno della settimana della cultura corrente e il giorno corrente, quindi sottrai il numero di giorni dal giorno corrente

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

0

A seguito di Compilare questa 'risposta, utilizzare il seguente metodo per ottenere la data per qualsiasi giorno della settimana:

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

Prova a creare una funzione che utilizza la ricorsione. L'oggetto DateTime è un input e la funzione restituisce un nuovo oggetto DateTime che rappresenta l'inizio della settimana.

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

Sebbene questo codice possa risolvere la domanda, inclusa una spiegazione di come e perché questo risolva il problema, contribuirebbe davvero a migliorare la qualità del tuo post e probabilmente darebbe più voti positivi. Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo per la persona che chiede ora. Si prega di modificare la risposta per aggiungere spiegazioni e dare un'indicazione di ciò si applicano le limitazioni e le assunzioni.
David Buck,

0

Il calcolo in questo modo ti consente di scegliere quale giorno della settimana indica l'inizio di una nuova settimana (nell'esempio che ho scelto lunedì).

Notare che questo calcolo per un giorno che è un lunedì darà il lunedì corrente e non quello precedente.

//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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.