0

I'm wondering how can I calculate what is the week of the month based on the ordinal number of the week of the year. For example I'm dealing with week 33, I should know that's Week 2 in august. I allready calculated months but now I'm dealing with weeks.

I allready have a solution, but it seems dirty to me..

Here's the code:

var data = query.GroupBy(x => CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(x.CreatedDate ?? DateTime.UtcNow, CalendarWeekRule.FirstDay, DayOfWeek.Monday))
.Select(article => new ArticleSimpleObject
{
    Week = GetWeekNumberOfMonth(article.FirstOrDefault().CreatedDate.Value),
    Amount = article.Sum(x => x.Amount),
    Month = article.FirstOrDefault().CreatedDate.Value.Month
});

And here's the method which I used to get week numbers:

 private static int GetWeekNumberOfMonth(DateTime date)
 {
      date = date.Date;
      DateTime firstMonthDay = new DateTime(date.Year, date.Month, 1);
      DateTime firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
      if (firstMonthMonday > date)
      {
          firstMonthDay = firstMonthDay.AddMonths(-1);
          firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
       }
      return (date - firstMonthMonday).Days / 7 + 1;
  }

As I wrote guys, this solutions works,

but I personally don't like it, I guess there is more elegant solution, and that's why I posted this question to help to myself and to future readers if some experienced person helps us to solve this :)

Maybe this could be solved based on Calendar class https://learn.microsoft.com/en-us/dotnet/api/system.globalization.calendar?view=netframework-4.8

I've tried some variant but I was not even close to solve it..

Thanks guys

Cheers

Roxy'Pro
  • 4,216
  • 9
  • 40
  • 102
  • Check this [related question](https://stackoverflow.com/questions/11154673/get-the-correct-week-number-of-a-given-date) – Cleptus Sep 21 '19 at 09:53
  • Why do you need to calculate the week of month based on an ordinal number when you already have a `GetWeekNumberOfMonth` method that accepts a date? – mm8 Sep 23 '19 at 14:39
  • @mm8 Yeah there's a GetWeekNumberOfMonth method but I was wondering if there's some more elegant solution with calendar class or smth like that. – Roxy'Pro Sep 24 '19 at 07:12
  • 1
    Possible duplicate of [Calculate week of month in .NET](https://stackoverflow.com/questions/2136487/calculate-week-of-month-in-net) – khellang Sep 24 '19 at 07:23
  • Your description says calculate the week of the month based on the week of the year but your code seems unrelated to that. What is it you actually want to accomplish? What Day of the Week starts the week for you? – NetMage Sep 24 '19 at 17:43

2 Answers2

-1

One approach is to subtract the week of the year of the 1st day of the month of the date from the week of the year of the date. Like so:

void Main()
{
    Console.WriteLine(DateTime.Now.GetWeekOfMonth());       
}

public static class MyDateTimeExtensions
{
    private static GregorianCalendar _calendar = new GregorianCalendar();

    public static int GetWeekOfMonth(this DateTime date)
    {
        return 
            date.GetWeekOfYear()
            - new DateTime(date.Year, date.Month, 1).GetWeekOfYear()
            + 1;
    }

    private static int GetWeekOfYear(this DateTime date)
    {
        return _calendar.GetWeekOfYear(
            date, 
            CalendarWeekRule.FirstDay, 
            DayOfWeek.Sunday);
    }
}

This outputs 4 for the current date: Sept. 23rd, 2019.

Carlo Bos
  • 3,105
  • 2
  • 16
  • 29
  • @khellang you are right that answer has the same approach. I should have checked for existing answers. – Carlo Bos Sep 24 '19 at 12:59
  • @NetMage The solution I posted (which was pointed out uses the same approach as a previous answer) does not return 0 but rather returns 1 for both dates you mentioned. However the question of full-week is interesting, but not mentioned in the original question. If full week is desired, you would indeed need to know which day of the week is considered the first day of the week (traditionally that would be Sunday). – Carlo Bos Sep 25 '19 at 16:30
  • @CarloBos It is all in the code in the method `GetWeekNumberOfMonth`. The week starts on Monday, the week one starts on the first Monday of the month. – NetMage Sep 25 '19 at 19:17
  • @CarloBos You are right, I think I missed the `+1` at the end of the `return`. – NetMage Sep 25 '19 at 19:38
-1

You can write a couple of general extensions to compute this a little bit simpler.

First, you need the first date of the week starting on a particular day of week for a date:

public static DateTime FirstDateOfWeekStarting(this DateTime aDate, DayOfWeek dow) => aDate.Date.AddDays((int)dow - (int)aDate.DayOfWeek);

Then, you can easily convert the day of month of that first date to the Week Number in the month:

public static int WeekStartingDOWNumOfMonth(this DateTime aDate, DayOfWeek dow) => (aDate.FirstDateOfWeekStarting(dow).Day-1) / 7 + 1;

And, for your specific case of weeks beginning with Monday,

public static int WeekStartingMonNumOfMonth(this DateTime aDate) => aDate.WeekStartingDOWNumOfMonth(DayOfWeek.Monday);
NetMage
  • 26,163
  • 3
  • 34
  • 55