GateKiller
GateKiller

Reputation: 75869

How can I get the DateTime for the start of the week?

How do I find the start of the week (both Sunday and Monday) knowing just the current time in C#?

Something like:

DateTime.Now.StartWeek(Monday);

Upvotes: 591

Views: 398961

Answers (30)

user8604852
user8604852

Reputation: 1

I did it like this: (2 links in case one doesn't work)

https://dotnetfiddle.net/rQ5D4U

https://dotnetfiddle.net/gGytcw

using System;

public class Program
{
    public static void Main()
    {
        TestClass testClass = new TestClass();
        //Use As Regular Method
        Console.WriteLine(testClass.GetDay(DateTime.Now).ToString("dddd, dd/MM/yyyy:HH:ss")); //Getting Monday
        Console.WriteLine(testClass.GetDayOfWeek(DateTime.Now).ToString("dddd, dd/MM/yyyy:HH:ss")); //Getting Monday
        Console.WriteLine(testClass.GetDay(DateTime.Now, 3).ToString("dddd, dd/MM/yyyy:HH:ss")); //Getting Wednesday        
        Console.WriteLine(testClass.GetDayOfWeek(DateTime.Now, DayOfWeek.Wednesday).ToString("dddd, dd/MM/yyyy:HH:ss")); //Getting Wednesday    
        //Use As Extension Method
        Console.WriteLine(DateTime.Now.GetDay().ToString("dddd, dd/MM/yyyy:HH:ss")); //Getting Monday
        Console.WriteLine(DateTime.Now.GetDayOfWeek().ToString("dddd, dd/MM/yyyy:HH:ss")); //Getting Monday
        Console.WriteLine(DateTime.Now.GetDay(3).ToString("dddd, dd/MM/yyyy:HH:ss")); //Getting Wednesday
        Console.WriteLine(DateTime.Now.GetDayOfWeek(DayOfWeek.Wednesday).ToString("dddd, dd/MM/yyyy:HH:ss")); //Getting Wednesday
    }
}

public class TestClass
{
    public DateTime GetDay(DateTime date, int daysAmount = 1)
    {
        return date.Date.AddDays(-(date.Date.DayOfWeek == 0 ? 7 : (int)date.Date.DayOfWeek) + daysAmount);
    }

    public DateTime GetDayOfWeek(DateTime date, DayOfWeek dayOfWeek = DayOfWeek.Monday)
    {
        return date.Date.AddDays(-(date.Date.DayOfWeek == 0 ? 7 : (int)date.Date.DayOfWeek) + (dayOfWeek == 0 ? 7 : (int)dayOfWeek));
    }
}

public static class TestClass2
{
    public static DateTime GetDay(this DateTime date, int daysAmount = 1)
    {
        return date.Date.AddDays(-(date.Date.DayOfWeek == 0 ? 7 : (int)date.Date.DayOfWeek) + daysAmount);
    }

    public static DateTime GetDayOfWeek(this DateTime date, DayOfWeek dayOfWeek = DayOfWeek.Monday)
    {
        return date.Date.AddDays(-(date.Date.DayOfWeek == 0 ? 7 : (int)date.Date.DayOfWeek) + (dayOfWeek == 0 ? 7 : (int)dayOfWeek));
    }
}

Upvotes: -1

user8604852
user8604852

Reputation: 1

I did it like this:

DateTime.Now.Date.AddDays(-(DateTime.Now.Date.DayOfWeek == 0 ? 7 : (int)DateTime.Now.Date.DayOfWeek) + 1)

All this code does is subtracting a number of days from the given datetime.

If day of week is 0(sunday) then subtract 7 else subtract the day of the week.

Then add 1 day to the result of the previous line, which gives you the monday of that date.

This way you can play around with the number(1) at the end to get the desired day.

private static DateTime GetDay(DateTime date, int daysAmount = 1)
{
    return date.Date.AddDays(-(date.Date.DayOfWeek == 0 ? 7 : (int)date.Date.DayOfWeek) + daysAmount);
}

If you really want to use the DayOfWeek enum then something like this can be used... though I presonally prefer the above one, as I can add or subtract any amount of days.

private static DateTime GetDayOfWeek(DateTime date, DayOfWeek dayOfWeek = DayOfWeek.Monday)
{
    return date.Date.AddDays(-(date.Date.DayOfWeek == 0 ? 7 : (int)date.Date.DayOfWeek) + (dayOfWeek == 0 ? 7 : (int)dayOfWeek));
}

Upvotes: -2

DReact
DReact

Reputation: 266

I did it for Monday, but with similar logic for Sunday.

public static DateTime GetStartOfWeekDate()
{
    // Get today's date
    DateTime today = DateTime.Today;
    // Get the value for today. DayOfWeek is an enum with 0 being Sunday, 1 Monday, etc
    var todayDayOfWeek = (int)today.DayOfWeek;

    var dateStartOfWeek = today;
    // If today is not Monday, then get the date for Monday
    if (todayDayOfWeek != 1)
    {
        // How many days to get back to Monday from today
        var daysToStartOfWeek = (todayDayOfWeek - 1);
        // Subtract from today's date the number of days to get to Monday
        dateStartOfWeek = today.AddDays(-daysToStartOfWeek);
    }

    return dateStartOfWeek;

}

Upvotes: 3

Rowan Richards
Rowan Richards

Reputation: 399

Following on from Compile This' answer, use the following method to obtain the date for any day of the week:

public static DateTime GetDayOfWeek(DateTime dateTime, DayOfWeek dayOfWeek)
{
   var monday = dateTime.Date.AddDays((7 + (dateTime.DayOfWeek - DayOfWeek.Monday) % 7) * -1);

   var diff = dayOfWeek - DayOfWeek.Monday;

   if (diff == -1)
   {
      diff = 6;
   }

   return monday.AddDays(diff);
}

Upvotes: 1

Muhammad Abbas
Muhammad Abbas

Reputation: 409

Step 1:

Create a static class

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

Step 2: Use this class to get both start and end day of the week

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

Upvotes: 7

user1489673
user1489673

Reputation:

We like one-liners: Get the difference between the current culture's first day of week and the current day, and then subtract the number of days from the current day:

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

Upvotes: 0

Ali Umair
Ali Umair

Reputation: 1424

If you want Saturday or Sunday or any day of week, but not exceeding the current week (Sat-Sun), I got you covered with this piece of code.

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

Upvotes: 0

Mike
Mike

Reputation: 1673

Here is a combination of a few of the answers. It uses an extension method that allows the culture to be passed in. If one is not passed in, the current culture is used. This will give it maximum flexibility and reuse.

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

Example Usage:

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

Upvotes: 0

F.H.
F.H.

Reputation: 1664

The same for end of the week (in style of Compile This's answer):

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

Upvotes: 3

Threezool
Threezool

Reputation: 453

I tried several, but I did not solve the issue with a week starting on a Monday, resulting in giving me the coming Monday on a Sunday. So I modified it a bit and got it working with this code:

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

Upvotes: 3

Piotr Lewandowski
Piotr Lewandowski

Reputation: 39

Modulo in C# works bad for -1 mod 7 (it should be 6, but C# returns -1) so... a "one-liner" solution to this will look like this :)

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

Upvotes: 3

Andreas Kromann
Andreas Kromann

Reputation: 191

Here is a correct solution. The following code works regardless if the first day of the week is a Monday or a Sunday or something else.

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

Upvotes: 2

Eric
Eric

Reputation: 2265

The quickest way I can come up with is:

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

If you would like any other day of the week to be your start date, all you need to do is add the DayOfWeek value to the end

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

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

Upvotes: 127

consequence007
consequence007

Reputation: 2160

Try with this in C#. With this code you can get both the first date and last date of a given week. Here Sunday is the first day and Saturday is the last day, but you can set both days according to your culture.

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

Upvotes: 3

Compile This
Compile This

Reputation: 12210

Use an extension method:

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

Which can be used as follows:

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

Upvotes: 953

Logopolitan
Logopolitan

Reputation: 191

I work with a lot of schools, so correctly using Monday as the first day of the week is important here.

A lot of the most terse answers here don't work on Sunday -- we often end up returning the date of tomorrow on Sunday, which is not good for running a report on last week's activities.

Here's my solution, which returns last Monday on Sunday, and today on Monday.

// Adding 7 so remainder is always positive; Otherwise % returns -1 on Sunday.
var daysToSubtract = (7 + (int)today.DayOfWeek - (int)DayOfWeek.Monday) % 7;

var monday = today
    .AddDays(-daysToSubtract)
    .Date;

Remember to use a method parameter for "today" so it's unit testable!!

Upvotes: 0

C. Keats
C. Keats

Reputation: 101

Calculating this way lets you choose which day of the week indicates the start of a new week (in the example I chose Monday).

Note that doing this calculation for a day that is a Monday will give the current Monday and not the previous one.

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

Upvotes: 0

Jason Navarrete
Jason Navarrete

Reputation: 7523

A little more verbose and culture-aware:

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;

Upvotes: 75

George Stavrou
George Stavrou

Reputation: 532

For Monday

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

For Sunday

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

Upvotes: 15

Rabbex
Rabbex

Reputation: 141

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

Upvotes: 6

Adrian
Adrian

Reputation: 1

   d = DateTime.Now;
            int dayofweek =(int) d.DayOfWeek;
            if (dayofweek != 0)
            {
                d = d.AddDays(1 - dayofweek);
            }
            else { d = d.AddDays(-6); }

Upvotes: -2

Denis
Denis

Reputation: 923

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

Upvotes: -1

HelloWorld
HelloWorld

Reputation: 3739

var now = System.DateTime.Now;

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

Upvotes: 4

Simon
Simon

Reputation: 34830

Using Fluent DateTime:

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

Upvotes: 40

Matthew Hintzen
Matthew Hintzen

Reputation: 518

Putting it all together, with Globalization and allowing for specifying the first day of the week as part of the call we have

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;

}

Upvotes: 5

Skizz
Skizz

Reputation: 71060

This would give you the preceding Sunday (I think):

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

Upvotes: 12

Janspeed
Janspeed

Reputation: 473

Ugly but it at least gives the right dates back

With start of week set by system:

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

Without:

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

Upvotes: 44

mails2008
mails2008

Reputation: 1

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

Upvotes: -2

Glenn Slaven
Glenn Slaven

Reputation: 34183

This would give you midnight on the first Sunday of the week:

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

This gives you the first Monday at midnight:

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

Upvotes: 3

Zamir
Zamir

Reputation: 1

This will return both the beginning of the week and the end of the week dates:

    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;

    }

I have posted the complete code for calculating the begin/end of week, month, quarter and year on my blog ZamirsBlog

Upvotes: 0

Related Questions