How to get the number of weeks in a date range in C#?

Asked

Viewed 1,583 times

3

I would like to know how to know the number of weeks in a given date range in C#.

  • 2

    Set week. Do you want to know how many Mondays (or other days) there are between a date and another? Or just the amount of days divided by 7?

5 answers

3

There are several ways depending on what you are considering as being a week.

Whole weeks of the calendar

Considering only whole weeks of the calendar, that is, only calendar weeks are counted that are fully inserted in the range:

public static int SemanasInteirasDoCalendario(DateTime d1, DateTime d2)
{
    if (d2 < d1) throw new ArgumentException(
        "'d1' precisa ser menor ou igual que 'd2'");
    return ((d2 - d1).Days + 1
        - ((int)d1.DayOfWeek > 0 ? 6 - (int)d1.DayOfWeek : 0)
        - ((int)d2.DayOfWeek < 6 ? (int)d2.DayOfWeek : 0)) / 7;
}

Partial calendar weeks

Consider any calendar week where at least one day of this week is within the range:

public static int SemanasParciaisDoCalendario(DateTime d1, DateTime d2)
{
    return SemanasInteirasDoCalendario(d1, d2)
        + ((int)d1.DayOfWeek > 0 ? 1 : 0)
        + ((int)d2.DayOfWeek < 6
            && d1.Date.AddDays(-(int)d1.DayOfWeek) != d2.Date.AddDays(-(int)d2.DayOfWeek)
            ? 1 : 0);
}

Whole weeks

Consider whole intervals of 7 consecutive days that are within the past date range:

public static int SemanasInteiras(DateTime d1, DateTime d2)
{
    if (d2 < d1) throw new ArgumentException(
        "'d1' precisa ser menor ou igual que 'd2'");
    return ((d2 - d1).Days + 1) / 7;
}

Partial weeks

Consider intervals of 7 days when at least one of the days appears within the date range:

public static int SemanasParciais(DateTime d1, DateTime d2)
{
    if (d2 < d1) throw new ArgumentException(
        "'d1' precisa ser menor ou igual que 'd2'");
    var days = (d2 - d1).Days + 1;
    return days / 7 + Math.Sign(days % 7);
}

Entire weeks of work

Consider only whole weeks of work (Monday through Friday) that are inserted within the last interval:

public static int SemanasInteirasDeTrabalho(DateTime d1, DateTime d2)
{
    if (d2 < d1) throw new ArgumentException(
        "'d1' precisa ser menor ou igual que 'd2'");
    return ((d2 - d1).Days + 1
        - ((int)d1.DayOfWeek > 1 ? 6 - (int)d1.DayOfWeek : -(int)d1.DayOfWeek)
        - ((int)d2.DayOfWeek < 5 ? (int)d2.DayOfWeek : (int)d2.DayOfWeek - 6)) / 7;
}

Partial weeks of work

Consider any workweek (Monday through Friday) in which at least one of the days is within the past date range:

public static int SemanasParciaisDeTrabalho(DateTime d1, DateTime d2)
{
    return SemanasInteirasDeTrabalho(d1, d2)
        + ((int)d1.DayOfWeek > 1 && (int)d1.DayOfWeek < 6 ? 1 : 0)
        + ((int)d2.DayOfWeek < 5 && (int)d2.DayOfWeek > 0
            && d1.Date.AddDays(-(int)d1.DayOfWeek) != d2.Date.AddDays(-(int)d2.DayOfWeek)
            ? 1 : 0);
}

1

I could try this way:

public int NumeroDeSemanas(DateTime dataInicial, DateTime dataFinal)
{
   TimeSpan Span = dataFinal.Subtract(dataInicial);

   //Testa se a diferença é menor ou igual a 7 (número de dias em uma semana)
   if (Span.Days <= 7)
   {
      if (dataInicial.DayOfWeek > dataFinal.DayOfWeek)
      {
         return 2;
      }

      return 1;
   }

   int Dias = Span.Days - 7 + (int)dataInicial.DayOfWeek;
   int SemanasCount = 1;
   int DiasCount = 0;

   for (SemanasCount = 1; DiasCount < Dias; SemanasCount++)
   {
      DiasCount += 7;
   }

   return SemanasCount;
}

As a parameter for this method you pass the start date and the end date, and the method returns the number of weeks.

1

Try to use this, simpler:

    public int totalSemanas(DateTime dataInicial, DateTime dataFim)
    {
        return (dataFim - dataInicial).Days / 7;
    }
  • 1

    is simpler, but in my opinion, incorrect. By your method, from 16/02/2014 until 25/02/2014, is counted only one week. Since the 23rd, 24th and 25th are already part of the second week, which was not accounted for by your algorithm.

  • It depends on the point of view and the need as well. Anything makes a Math.Round() for it to go up. But, well raised its placement.

0

Try this method:

public int totalSemanas(DateTime dataInicial, DateTime dataFim)
{
    return (int)Math.Ceiling(((dataFim- dataInicial).TotalDays + 1) / 7d);
}

Or this:

public int GetCalendarWeeks(DateTime startDate, DateTime endDate)
{
    return (endDate.GetBeginningOfWeek().Subtract(startDate.GetBeginningOfWeek()).Days / 7) + 1;
}

public static DateTime GetBeginningOfWeek(this DateTime date)
{
    var dayOfWeekOffSet = date.DayOfWeek == DayOfWeek.Sunday ? 6 : ((int)date.DayOfWeek) - 1;
    return date.AddDays(-1 * dayOfWeekOffSet).Date;
}

public static DateTime GetEndOfWeek(this DateTime date)
{
    var dayOfWeekOffSet = date.DayOfWeek == DayOfWeek.Sunday ? 0 : 7 - ((int)date.DayOfWeek);
    return date.AddDays(dayOfWeekOffSet).Date;
}

0

In the there is the function dateDiff that helps you in this. And to use in c#, just add the reference "Microsoft.VisualBasic" in its project, and to include the namespace in your class:

using Microsoft.VisualBasic;

Follow example of code:

        DateTime x = DateTime.Today.AddDays(-31);
        DateTime y = DateTime.Today;

        long l = DateAndTime.DateDiff(DateInterval.WeekOfYear, x, y);
        long ll = DateAndTime.DateDiff(DateInterval.Weekday, x, y);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.