André Luiz
André Luiz

Reputation: 7302

Week difference between 2 dates in C#

I'm trying to make a function in C# that returns the week difference between two dates. Its goal is to provide the same result of:

select datediff(ww,'2018-04-13','2018-04-16') as diff

In the example above there is only 3 days between these dates, but they are in different weeks, so the result should be 1.

I've tried to use .TotalDays but it's not working properly. I also tried .GetWeekOfYear but it won't return correctly when the year of the dates are different. I've seem many questions here on StackOverflow and on other forums and so far none of them match my case. This is the function I'm trying to far:

public static int GetWeekDiff(DateTime dtStart, DateTime dtEnd) {
    // Doesn't work
    var val = ((dtEnd - dtStart).TotalDays / 7);
    val = Math.Ceiling(val);
    return Convert.ToInt32(val);

    // Doesn't work well between years
    DateTimeFormatInfo dinfo = DateTimeFormatInfo.CurrentInfo;
    var x = dinfo.Calendar.GetWeekOfYear(dtStart, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
    var y = dinfo.Calendar.GetWeekOfYear(dtEnd, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);

    return y - x;

}

In the first part of my function, I tried what is described in this post. It didn't work

Can you help me? Thanks in advance.

Upvotes: 3

Views: 5157

Answers (6)

SANM2009
SANM2009

Reputation: 1998

This is my implementation to solve a similar problem, I haven't tested in thoroughly but it seems to work.

        var dt1 = DateTime.Today.AddDays(-30);
        var dt2 = DateTime.Today;

        var noOfDays =(int) (dt2 - dt1).TotalDays;
        int reminder;
        var weeks = Math.DivRem(noOfDays, 7, out reminder);
        weeks = reminder > 0 ? weeks + 1 : weeks;

It returns 1 week for 6 days or less gap, which is exactly what I needed.

Upvotes: 0

Chrᴉz remembers Monica
Chrᴉz remembers Monica

Reputation: 1904

static void Main(string[] args)
{
    DateTime date1 = new DateTime(2018, 04, 18);
    DateTime date2 = new DateTime(2018, 04, 19);


    System.Console.WriteLine((GetDiff(new DateTime(2018, 04, 18), new DateTime(2018, 04, 18)))); // 0
    System.Console.WriteLine((GetDiff(new DateTime(2018, 04, 22), new DateTime(2018, 04, 23)))); // 1
    System.Console.WriteLine((GetDiff(new DateTime(2018, 04, 16), new DateTime(2018, 04, 22)))); // 0
    System.Console.WriteLine((GetDiff(new DateTime(2018, 04, 18), new DateTime(2018, 05, 03)))); // 2
}

private static int GetDiff(DateTime date1, DateTime date2)
{
    date1 = SetDayToMonday(date1);
    date2 = SetDayToMonday(date2);

    return (int)((date2 - date1).TotalDays / 7);
}

private static DateTime SetDayToMonday(DateTime date)
{ 
    var weekDay = date.DayOfWeek;
    if (weekDay == DayOfWeek.Sunday)
        return date.AddDays(-6);
    else
        return date.AddDays(-((int)weekDay-1));
}

First, set the day to the monday of the current week. Then count all full weeks(= /7 days as int). Easy as it is, it works probably across weeks and years.

Upvotes: 2

Leustherin
Leustherin

Reputation: 51

Can't comment yet and already used a flag on this post on something I believed to be similar. Here is another post I found that appears to align with the solution you are trying to create:

Get the number of calendar weeks between 2 dates in C#

Upvotes: 0

phuzi
phuzi

Reputation: 13059

First figure how many days there are between the two dates. Divide the number of days by 7 to get full weeks.

Now figure out if there's an extra week to be counted by finding taking the number of days modulus 7 to get any remaining days. If the first date plus remaining days falls in a different week, add an extra week on to the count.

void Main()
{

    var first = new DateTime(2018, 04, 13);
    var second = new DateTime(2018, 04, 16);

    Console.WriteLine(weekDiff(first, second));
}

public int weekDiff(DateTime d1, DateTime d2, DayOfWeek startOfWeek = DayOfWeek.Monday)
{
    var diff = d2.Subtract(d1);

    var weeks = (int)diff.Days / 7;

    // need to check if there's an extra week to count
    var remainingDays = diff.Days % 7;
    var cal = CultureInfo.InvariantCulture.Calendar;
    var d1WeekNo = cal.GetWeekOfYear(d1, CalendarWeekRule.FirstFullWeek, startOfWeek);
    var d1PlusRemainingWeekNo = cal.GetWeekOfYear(d1.AddDays(remainingDays), CalendarWeekRule.FirstFullWeek, startOfWeek);

    if (d1WeekNo != d1PlusRemainingWeekNo)
        weeks++;

    return weeks;
}

Upvotes: 4

Dan Wilson
Dan Wilson

Reputation: 4047

See if this works. There could be more use cases that this doesn't cover, and the solution depends on how you define a week boundary (this assumes Sunday-Monday based on a comment above).

// Output:
// Weeks between 12/28/2017 and 1/10/2018: 2
// Weeks between 4/13/2018 and 4/16/2018: 1
// Weeks between 4/21/2018 and 4/22/2018: 0
// Weeks between 4/22/2018 and 4/23/2018: 1

void Main()
{
    var datePairs = new List<KeyValuePair<DateTime, DateTime>>();
    datePairs.Add(new KeyValuePair<DateTime, DateTime>(new DateTime(2017, 12, 28), new DateTime(2018, 1, 10)));
    datePairs.Add(new KeyValuePair<DateTime, DateTime>(new DateTime(2018, 4, 13), new DateTime(2018, 4, 16)));
    datePairs.Add(new KeyValuePair<DateTime, DateTime>(new DateTime(2018, 4, 21), new DateTime(2018, 4, 22)));
    datePairs.Add(new KeyValuePair<DateTime, DateTime>(new DateTime(2018, 4, 22), new DateTime(2018, 4, 23)));

    foreach (var datePair in datePairs)
    {
        var string1 = datePair.Key.ToShortDateString();
        var string2 = datePair.Value.ToShortDateString();
        Console.WriteLine($"Weeks between {string1} and {string2}: {GetWeekDiff(datePair.Key, datePair.Value)}");
    }
}

public static int GetWeekDiff(DateTime dtStart, DateTime dtEnd)
{
    var totalDays = (dtEnd - dtStart).TotalDays;
    var weeks = (int)totalDays / 7;
    var hasRemainder = totalDays % 7 > 0;
    if (hasRemainder)
    {
        if (!(dtStart.DayOfWeek.Equals(DayOfWeek.Saturday) && dtEnd.DayOfWeek.Equals(DayOfWeek.Sunday)))
        {
            weeks++;
        }
    }
    return weeks;
}

Upvotes: 1

Artyom Shmarlovsky
Artyom Shmarlovsky

Reputation: 51

Maybe it can help

    public static int GetIso8601WeekOfYear(DateTime time)
    {
        // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
        // be the same week# as whatever Thursday, Friday or Saturday are,
        // and we always get those right
        DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
        if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
        {
            time = time.AddDays(3);
        }

        // Return the week of our adjusted day
        return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    }

Get the correct week number of a given date

Upvotes: 0

Related Questions