Domanda

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

Qualcosa di simile a:

DateTime.Now.StartWeek(Monday);
È stato utile?

Soluzione

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

Che può essere utilizzato come segue:

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

Altri suggerimenti

Il modo più rapido che posso trovare è:

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

Se desideri che qualsiasi altro giorno della settimana sia la 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);

Un po’ più prolisso e consapevole della 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;

Utilizzando DateTime fluente:

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

Brutto ma almeno restituisce le date giuste

Con inizio settimana impostato da 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;
    }

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

Questo potrebbe essere un po' un trucco, ma puoi eseguire il cast della proprietà .DayOfWeek su un int (è un enum e poiché non è stato modificato il tipo di dati sottostante, il valore predefinito è int) e usarlo per determinare l'inizio precedente della settimana .

Sembra che la settimana specificata nell'enumerazione DayOfWeek inizi di domenica, quindi se sottraiamo 1 da questo valore sarà uguale a quanti giorni il lunedì precede la data corrente.Dobbiamo anche mappare la domenica (0) su 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 dobbiamo apportare questa modifica: -

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

Questo ti darebbe la domenica precedente (credo):

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

Per lunedì

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

Per domenica

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

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;

}
var now = System.DateTime.Now;

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

Questo ti darebbe la mezzanotte della 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);

prova con questo in C#. Con questo codice puoi ottenere sia la prima data che l'ultima data di una determinata settimana. Qui domenica è il primo giorno e 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;
}

Ne ho provati diversi ma non ho risolto il problema con una settimana che iniziava di lunedì, con il risultato di darmi il lunedì successivo 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;

Il metodo seguente dovrebbe restituire il DateTime desiderato.Passa vero perché domenica è 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);
}

Grazie per gli esempiAvevo bisogno di utilizzare sempre il primo giorno della settimana "CurrentCulture" e per un array avevo bisogno di conoscere l'esatto numero del giorno.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
    }
}

Nessuno sembra aver ancora risposto correttamente.Incollerò qui la mia soluzione nel caso qualcuno ne avesse bisogno.Il seguente codice funziona indipendentemente dal fatto che il primo giorno della settimana sia lunedì, 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());
  }
}

Modulo in C# funziona male per -1mod7 (dovrebbe essere 6, C# restituisce -1) quindi ...La soluzione "oneliner" a questo sarà simile a questa :)

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

Lo stesso per la fine della settimana (nello stile di @Compile Questa 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) { };
    }

Passo 1:Crea 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;
    }
}

Passo 2:Utilizza questa lezione per ottenere sia il giorno di inizio che quello di fine della settimana

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

Potresti usare l'eccellente Biblioteca dell'ombrello:

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

Tuttavia, loro Fare sembra che abbia memorizzato lunedì come primo giorno della settimana (vedi proprietà nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn), quindi la soluzione localizzata precedente è leggermente migliore.Sfortunato.

Modificare:guardando più da vicino la domanda, sembra che Umbrella potrebbe effettivamente 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 verranno restituiti sette giorni.Ma questo vale anche se usi BeginningOfWeek, che sembra un bug :(.

Ciò restituirà sia le date di inizio settimana che quelle di fine 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 sul mio blog il codice completo per il calcolo dell'inizio/fine settimana, mese, trimestre e annoZamirsBlog

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

Ecco una combinazione di alcune delle risposte.Utilizza un metodo di estensione che consente di passare la cultura, se non ne viene passata una, viene utilizzata la lingua corrente.Ciò gli darà 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()}");
        }
    }

se vuoi sabato o domenica o qualsiasi giorno della settimana ma non superiore alla settimana corrente (sabato-domenica), ti coprirò con questo pezzo di 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;
}

Ci piacciono le battute semplici: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));
   d = DateTime.Now;
            int dayofweek =(int) d.DayOfWeek;
            if (dayofweek != 0)
            {
                d = d.AddDays(1 - dayofweek);
            }
            else { d = d.AddDays(-6); }
public static System.DateTime getstartweek()
{
    System.DateTime dt = System.DateTime.Now;
    System.DayOfWeek dmon = System.DayOfWeek.Monday;
    int span = dt.DayOfWeek - dmon;
    dt = dt.AddDays(-span);
    return dt;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top