How to Get the number of weeks in a given year












2















Trying to code a correct function that returns the number of weeks in a given year, but without success.



Example of the function I'm looking for :



int weeks =  GetWeeksInYear ( 2012 )


should return 52 weeks // means there are only 52 weeks in 2012.



P.s.: in a year can be 52, 53, 54 weeks, not sure about 51










share|improve this question




















  • 4





    the number of weeks is the same every year. (given the case you have an int...) the only difference (when using a double) would be leap years (where you have one day more)

    – Vogel612
    Jun 30 '13 at 13:58






  • 6





    It entirely depends on what you mean by "week". If you're talking "week of ISO week year" then it can definitely vary between 52 and 53. If you mean something else, you'll need to be very specific.

    – Jon Skeet
    Jun 30 '13 at 14:03






  • 6





    @Vogel612: No, there really aren't. For one thing, you're assuming a Gregorian calendar. For another, you're assuming one meaning of "week" - and there are various different options available. The OP definitely needs to be clearer, but it's not as simple as "there are always 52 weeks".

    – Jon Skeet
    Jun 30 '13 at 14:04






  • 2





    @svick this is not a debate, he should be more specific next time, if a question has so many comments, and only 1 answer.. the question is not specific enough :)

    – ilansch
    Jun 30 '13 at 14:30






  • 3





    @illusion: I don't, because you didn't put any details into your question. Hint hint. (54 weeks in a year must be in a calendar I haven't come across before, mind you.)

    – Jon Skeet
    Jun 30 '13 at 15:38


















2















Trying to code a correct function that returns the number of weeks in a given year, but without success.



Example of the function I'm looking for :



int weeks =  GetWeeksInYear ( 2012 )


should return 52 weeks // means there are only 52 weeks in 2012.



P.s.: in a year can be 52, 53, 54 weeks, not sure about 51










share|improve this question




















  • 4





    the number of weeks is the same every year. (given the case you have an int...) the only difference (when using a double) would be leap years (where you have one day more)

    – Vogel612
    Jun 30 '13 at 13:58






  • 6





    It entirely depends on what you mean by "week". If you're talking "week of ISO week year" then it can definitely vary between 52 and 53. If you mean something else, you'll need to be very specific.

    – Jon Skeet
    Jun 30 '13 at 14:03






  • 6





    @Vogel612: No, there really aren't. For one thing, you're assuming a Gregorian calendar. For another, you're assuming one meaning of "week" - and there are various different options available. The OP definitely needs to be clearer, but it's not as simple as "there are always 52 weeks".

    – Jon Skeet
    Jun 30 '13 at 14:04






  • 2





    @svick this is not a debate, he should be more specific next time, if a question has so many comments, and only 1 answer.. the question is not specific enough :)

    – ilansch
    Jun 30 '13 at 14:30






  • 3





    @illusion: I don't, because you didn't put any details into your question. Hint hint. (54 weeks in a year must be in a calendar I haven't come across before, mind you.)

    – Jon Skeet
    Jun 30 '13 at 15:38
















2












2








2


1






Trying to code a correct function that returns the number of weeks in a given year, but without success.



Example of the function I'm looking for :



int weeks =  GetWeeksInYear ( 2012 )


should return 52 weeks // means there are only 52 weeks in 2012.



P.s.: in a year can be 52, 53, 54 weeks, not sure about 51










share|improve this question
















Trying to code a correct function that returns the number of weeks in a given year, but without success.



Example of the function I'm looking for :



int weeks =  GetWeeksInYear ( 2012 )


should return 52 weeks // means there are only 52 weeks in 2012.



P.s.: in a year can be 52, 53, 54 weeks, not sure about 51







c# week-number






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 30 '13 at 14:24









svick

176k40297414




176k40297414










asked Jun 30 '13 at 13:55









illusionillusion

98228




98228








  • 4





    the number of weeks is the same every year. (given the case you have an int...) the only difference (when using a double) would be leap years (where you have one day more)

    – Vogel612
    Jun 30 '13 at 13:58






  • 6





    It entirely depends on what you mean by "week". If you're talking "week of ISO week year" then it can definitely vary between 52 and 53. If you mean something else, you'll need to be very specific.

    – Jon Skeet
    Jun 30 '13 at 14:03






  • 6





    @Vogel612: No, there really aren't. For one thing, you're assuming a Gregorian calendar. For another, you're assuming one meaning of "week" - and there are various different options available. The OP definitely needs to be clearer, but it's not as simple as "there are always 52 weeks".

    – Jon Skeet
    Jun 30 '13 at 14:04






  • 2





    @svick this is not a debate, he should be more specific next time, if a question has so many comments, and only 1 answer.. the question is not specific enough :)

    – ilansch
    Jun 30 '13 at 14:30






  • 3





    @illusion: I don't, because you didn't put any details into your question. Hint hint. (54 weeks in a year must be in a calendar I haven't come across before, mind you.)

    – Jon Skeet
    Jun 30 '13 at 15:38
















  • 4





    the number of weeks is the same every year. (given the case you have an int...) the only difference (when using a double) would be leap years (where you have one day more)

    – Vogel612
    Jun 30 '13 at 13:58






  • 6





    It entirely depends on what you mean by "week". If you're talking "week of ISO week year" then it can definitely vary between 52 and 53. If you mean something else, you'll need to be very specific.

    – Jon Skeet
    Jun 30 '13 at 14:03






  • 6





    @Vogel612: No, there really aren't. For one thing, you're assuming a Gregorian calendar. For another, you're assuming one meaning of "week" - and there are various different options available. The OP definitely needs to be clearer, but it's not as simple as "there are always 52 weeks".

    – Jon Skeet
    Jun 30 '13 at 14:04






  • 2





    @svick this is not a debate, he should be more specific next time, if a question has so many comments, and only 1 answer.. the question is not specific enough :)

    – ilansch
    Jun 30 '13 at 14:30






  • 3





    @illusion: I don't, because you didn't put any details into your question. Hint hint. (54 weeks in a year must be in a calendar I haven't come across before, mind you.)

    – Jon Skeet
    Jun 30 '13 at 15:38










4




4





the number of weeks is the same every year. (given the case you have an int...) the only difference (when using a double) would be leap years (where you have one day more)

– Vogel612
Jun 30 '13 at 13:58





the number of weeks is the same every year. (given the case you have an int...) the only difference (when using a double) would be leap years (where you have one day more)

– Vogel612
Jun 30 '13 at 13:58




6




6





It entirely depends on what you mean by "week". If you're talking "week of ISO week year" then it can definitely vary between 52 and 53. If you mean something else, you'll need to be very specific.

– Jon Skeet
Jun 30 '13 at 14:03





It entirely depends on what you mean by "week". If you're talking "week of ISO week year" then it can definitely vary between 52 and 53. If you mean something else, you'll need to be very specific.

– Jon Skeet
Jun 30 '13 at 14:03




6




6





@Vogel612: No, there really aren't. For one thing, you're assuming a Gregorian calendar. For another, you're assuming one meaning of "week" - and there are various different options available. The OP definitely needs to be clearer, but it's not as simple as "there are always 52 weeks".

– Jon Skeet
Jun 30 '13 at 14:04





@Vogel612: No, there really aren't. For one thing, you're assuming a Gregorian calendar. For another, you're assuming one meaning of "week" - and there are various different options available. The OP definitely needs to be clearer, but it's not as simple as "there are always 52 weeks".

– Jon Skeet
Jun 30 '13 at 14:04




2




2





@svick this is not a debate, he should be more specific next time, if a question has so many comments, and only 1 answer.. the question is not specific enough :)

– ilansch
Jun 30 '13 at 14:30





@svick this is not a debate, he should be more specific next time, if a question has so many comments, and only 1 answer.. the question is not specific enough :)

– ilansch
Jun 30 '13 at 14:30




3




3





@illusion: I don't, because you didn't put any details into your question. Hint hint. (54 weeks in a year must be in a calendar I haven't come across before, mind you.)

– Jon Skeet
Jun 30 '13 at 15:38







@illusion: I don't, because you didn't put any details into your question. Hint hint. (54 weeks in a year must be in a calendar I haven't come across before, mind you.)

– Jon Skeet
Jun 30 '13 at 15:38














3 Answers
3






active

oldest

votes


















15














See the Calendar.GetWeekOfYear method



public int GetWeeksInYear(int year)
{
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
DateTime date1 = new DateTime(year, 12, 31);
Calendar cal = dfi.Calendar;
return cal.GetWeekOfYear(date1, dfi.CalendarWeekRule,
dfi.FirstDayOfWeek);
}


Be carefull to figure out the correct CalendarWeekRule and FirstDayOfWeek for a Calendar that matches the culture your customers are used to. (for some calenders it might vary...)






share|improve this answer
























  • And, just as importantly, the OP should decide for himself what he is really asking.

    – Tormod
    Jun 30 '13 at 14:24






  • 7





    And note that none of the CalendarWeekRule options in .NET match ISO-8601, if that's what the OP wants...

    – Jon Skeet
    Jun 30 '13 at 14:46











  • I wouldn't be surprised to have new Question of the OP that asks for an implementation of a calendar that follows the company rules...been there, done that...

    – rene
    Jun 30 '13 at 15:01






  • 1





    when i give 2018 to year parameter after method returns 53 but it is not correct end of this year week is 52.

    – Murat Can OĞUZHAN
    Aug 2 '18 at 12:28






  • 1





    @MuratCanOĞUZHAN That is then a bug in the implementation as none of the cultures return 52. It might be that the lack of a proper ISO-8601 implementation is causing this. You might want to look into NodaTime, the library that Jon wrote for date and time handling

    – rene
    Aug 2 '18 at 13:03





















1














I had issue when i assign 2018 to year parameter of other methods.
I do not know maybe there are codes that work faster but i wrote following methods.



        //you can try like that 
int weeks = DateHelper.GetWeeksInGivenYear(2018);
int weeks = DateHelper.GetWeeksInGivenYear(2020);

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(this 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);
}

//gets given year last week no
public static int GetWeeksInGivenYear(int year)
{
DateTime lastDate = new DateTime(year, 12, 31);
int lastWeek = GetIso8601WeekOfYear(lastDate);

while (lastWeek == 1)
{
lastDate = lastDate.AddDays(-1);
lastWeek = GetIso8601WeekOfYear(lastDate);

}
return lastWeek;
}





share|improve this answer

































    1















    P.s.: in a year can be 52, 53, 54 weeks, not sure about 51




    1. If we will check With Calendar we will get results that we can have only 53 or 54 weeks.



    2. This is incorrect result (read the end of my answer)



    You can check it with the following app:



    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Globalization;
    using System.Linq;
    namespace TestConsoleApp
    {
    class Program
    {
    public static void Main(string args)
    {
    var b = CountWeeksForYearsRange(1, 4000);

    var c = b.Where(a => a.Value != 53).ToDictionary(a=>a.Key, a=>a.Value);
    }

    static DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
    static Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

    private static int CountWeeksInYear(int year)
    {
    DateTime date = new DateTime(year, 12, 31);
    return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
    }

    private static Dictionary<int,int> CountWeeksForYearsRange(int yearStart, int yearEnd)
    {
    Dictionary<int, int> rez = new Dictionary<int, int>();

    for (int i = yearStart; i <= yearEnd; i++)
    {
    rez.Add(i, CountWeeksInYear(i));
    }

    return rez;
    }
    }
    }


    and there will be only 53 and 54 values.



    This means that for faster work of method we can have pre-coded function for such situation.





    Years with not 53 weeks



    enter image description here





    Years with not 53 and not 54 weeks:



    enter image description here





    So in this case we can generate simple array of years that have 54 weeks from 0 to 4000 years:




    12,40,68,96,108,136,164,192,204,232,260,288,328,356,384,412,440,468,496,508,536,564,592,604,632,660,688,728,756,784,812,840,868,896,908,936,964,992,1004,1032,1060,1088,1128,1156,1184,1212,1240,1268,1296,1308,1336,1364,1392,1404,1432,1460,1488,1528,1556,1584,1612,1640,1668,1696,1708,1736,1764,1792,1804,1832,1860,1888,1928,1956,1984,2012,2040,2068,2096,2108,2136,2164,2192,2204,2232,2260,2288,2328,2356,2384,2412,2440,2468,2496,2508,2536,2564,2592,2604,2632,2660,2688,2728,2756,2784,2812,2840,2868,2896,2908,2936,2964,2992,3004,3032,3060,3088,3128,3156,3184,3212,3240,3268,3296,3308,3336,3364,3392,3404,3432,3460,3488,3528,3556,3584,3612,3640,3668,3696,3708,3736,3764,3792,3804,3832,3860,3888,3928,3956,3984




    And this is means that most optimized method will be:



    //Works only with 1-4000 years range
    public int CountWeeksInYearOptimized(int year)
    {
    return (_yearsWith54Weeks.IndexOf(year) == -1) ? 53 : 54;
    }
    private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
    204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
    592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
    964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
    1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
    1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
    1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
    2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
    2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
    3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
    3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
    3984 };


    or if you don't want to pre-calculated data:



        DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
    Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

    private int CountWeeksInYear(int year)
    {
    DateTime date = new DateTime(year, 12, 31);
    return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
    }


    UPD: BUT! Looks like this is incorrect way.



    I don't know why so, but looks like Calendar saying incorrect number. And correct count of weeks is always on less on 1 week. You can check it manually:




    Let's calc days in the following years with Calendar:



    2011+2012+2013:



    53+54+53=160 weeks.



    But stop!



    (365+366+365)/7 = 157.




    So best way will be to do -1 to the value that will be shown by calendar



    Or to use the following fastest method:



    //Works only with 1-4000 years range
    public int CountWeeksInYearOptimized(int year)
    {
    return (_yearsWith54Weeks.IndexOf(year) == -1) ? 52 : 53;
    }
    private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
    204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
    592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
    964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
    1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
    1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
    1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
    2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
    2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
    3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
    3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
    3984 };





    share|improve this answer


























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f17391073%2fhow-to-get-the-number-of-weeks-in-a-given-year%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      15














      See the Calendar.GetWeekOfYear method



      public int GetWeeksInYear(int year)
      {
      DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
      DateTime date1 = new DateTime(year, 12, 31);
      Calendar cal = dfi.Calendar;
      return cal.GetWeekOfYear(date1, dfi.CalendarWeekRule,
      dfi.FirstDayOfWeek);
      }


      Be carefull to figure out the correct CalendarWeekRule and FirstDayOfWeek for a Calendar that matches the culture your customers are used to. (for some calenders it might vary...)






      share|improve this answer
























      • And, just as importantly, the OP should decide for himself what he is really asking.

        – Tormod
        Jun 30 '13 at 14:24






      • 7





        And note that none of the CalendarWeekRule options in .NET match ISO-8601, if that's what the OP wants...

        – Jon Skeet
        Jun 30 '13 at 14:46











      • I wouldn't be surprised to have new Question of the OP that asks for an implementation of a calendar that follows the company rules...been there, done that...

        – rene
        Jun 30 '13 at 15:01






      • 1





        when i give 2018 to year parameter after method returns 53 but it is not correct end of this year week is 52.

        – Murat Can OĞUZHAN
        Aug 2 '18 at 12:28






      • 1





        @MuratCanOĞUZHAN That is then a bug in the implementation as none of the cultures return 52. It might be that the lack of a proper ISO-8601 implementation is causing this. You might want to look into NodaTime, the library that Jon wrote for date and time handling

        – rene
        Aug 2 '18 at 13:03


















      15














      See the Calendar.GetWeekOfYear method



      public int GetWeeksInYear(int year)
      {
      DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
      DateTime date1 = new DateTime(year, 12, 31);
      Calendar cal = dfi.Calendar;
      return cal.GetWeekOfYear(date1, dfi.CalendarWeekRule,
      dfi.FirstDayOfWeek);
      }


      Be carefull to figure out the correct CalendarWeekRule and FirstDayOfWeek for a Calendar that matches the culture your customers are used to. (for some calenders it might vary...)






      share|improve this answer
























      • And, just as importantly, the OP should decide for himself what he is really asking.

        – Tormod
        Jun 30 '13 at 14:24






      • 7





        And note that none of the CalendarWeekRule options in .NET match ISO-8601, if that's what the OP wants...

        – Jon Skeet
        Jun 30 '13 at 14:46











      • I wouldn't be surprised to have new Question of the OP that asks for an implementation of a calendar that follows the company rules...been there, done that...

        – rene
        Jun 30 '13 at 15:01






      • 1





        when i give 2018 to year parameter after method returns 53 but it is not correct end of this year week is 52.

        – Murat Can OĞUZHAN
        Aug 2 '18 at 12:28






      • 1





        @MuratCanOĞUZHAN That is then a bug in the implementation as none of the cultures return 52. It might be that the lack of a proper ISO-8601 implementation is causing this. You might want to look into NodaTime, the library that Jon wrote for date and time handling

        – rene
        Aug 2 '18 at 13:03
















      15












      15








      15







      See the Calendar.GetWeekOfYear method



      public int GetWeeksInYear(int year)
      {
      DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
      DateTime date1 = new DateTime(year, 12, 31);
      Calendar cal = dfi.Calendar;
      return cal.GetWeekOfYear(date1, dfi.CalendarWeekRule,
      dfi.FirstDayOfWeek);
      }


      Be carefull to figure out the correct CalendarWeekRule and FirstDayOfWeek for a Calendar that matches the culture your customers are used to. (for some calenders it might vary...)






      share|improve this answer













      See the Calendar.GetWeekOfYear method



      public int GetWeeksInYear(int year)
      {
      DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
      DateTime date1 = new DateTime(year, 12, 31);
      Calendar cal = dfi.Calendar;
      return cal.GetWeekOfYear(date1, dfi.CalendarWeekRule,
      dfi.FirstDayOfWeek);
      }


      Be carefull to figure out the correct CalendarWeekRule and FirstDayOfWeek for a Calendar that matches the culture your customers are used to. (for some calenders it might vary...)







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jun 30 '13 at 14:06









      renerene

      33.8k1181110




      33.8k1181110













      • And, just as importantly, the OP should decide for himself what he is really asking.

        – Tormod
        Jun 30 '13 at 14:24






      • 7





        And note that none of the CalendarWeekRule options in .NET match ISO-8601, if that's what the OP wants...

        – Jon Skeet
        Jun 30 '13 at 14:46











      • I wouldn't be surprised to have new Question of the OP that asks for an implementation of a calendar that follows the company rules...been there, done that...

        – rene
        Jun 30 '13 at 15:01






      • 1





        when i give 2018 to year parameter after method returns 53 but it is not correct end of this year week is 52.

        – Murat Can OĞUZHAN
        Aug 2 '18 at 12:28






      • 1





        @MuratCanOĞUZHAN That is then a bug in the implementation as none of the cultures return 52. It might be that the lack of a proper ISO-8601 implementation is causing this. You might want to look into NodaTime, the library that Jon wrote for date and time handling

        – rene
        Aug 2 '18 at 13:03





















      • And, just as importantly, the OP should decide for himself what he is really asking.

        – Tormod
        Jun 30 '13 at 14:24






      • 7





        And note that none of the CalendarWeekRule options in .NET match ISO-8601, if that's what the OP wants...

        – Jon Skeet
        Jun 30 '13 at 14:46











      • I wouldn't be surprised to have new Question of the OP that asks for an implementation of a calendar that follows the company rules...been there, done that...

        – rene
        Jun 30 '13 at 15:01






      • 1





        when i give 2018 to year parameter after method returns 53 but it is not correct end of this year week is 52.

        – Murat Can OĞUZHAN
        Aug 2 '18 at 12:28






      • 1





        @MuratCanOĞUZHAN That is then a bug in the implementation as none of the cultures return 52. It might be that the lack of a proper ISO-8601 implementation is causing this. You might want to look into NodaTime, the library that Jon wrote for date and time handling

        – rene
        Aug 2 '18 at 13:03



















      And, just as importantly, the OP should decide for himself what he is really asking.

      – Tormod
      Jun 30 '13 at 14:24





      And, just as importantly, the OP should decide for himself what he is really asking.

      – Tormod
      Jun 30 '13 at 14:24




      7




      7





      And note that none of the CalendarWeekRule options in .NET match ISO-8601, if that's what the OP wants...

      – Jon Skeet
      Jun 30 '13 at 14:46





      And note that none of the CalendarWeekRule options in .NET match ISO-8601, if that's what the OP wants...

      – Jon Skeet
      Jun 30 '13 at 14:46













      I wouldn't be surprised to have new Question of the OP that asks for an implementation of a calendar that follows the company rules...been there, done that...

      – rene
      Jun 30 '13 at 15:01





      I wouldn't be surprised to have new Question of the OP that asks for an implementation of a calendar that follows the company rules...been there, done that...

      – rene
      Jun 30 '13 at 15:01




      1




      1





      when i give 2018 to year parameter after method returns 53 but it is not correct end of this year week is 52.

      – Murat Can OĞUZHAN
      Aug 2 '18 at 12:28





      when i give 2018 to year parameter after method returns 53 but it is not correct end of this year week is 52.

      – Murat Can OĞUZHAN
      Aug 2 '18 at 12:28




      1




      1





      @MuratCanOĞUZHAN That is then a bug in the implementation as none of the cultures return 52. It might be that the lack of a proper ISO-8601 implementation is causing this. You might want to look into NodaTime, the library that Jon wrote for date and time handling

      – rene
      Aug 2 '18 at 13:03







      @MuratCanOĞUZHAN That is then a bug in the implementation as none of the cultures return 52. It might be that the lack of a proper ISO-8601 implementation is causing this. You might want to look into NodaTime, the library that Jon wrote for date and time handling

      – rene
      Aug 2 '18 at 13:03















      1














      I had issue when i assign 2018 to year parameter of other methods.
      I do not know maybe there are codes that work faster but i wrote following methods.



              //you can try like that 
      int weeks = DateHelper.GetWeeksInGivenYear(2018);
      int weeks = DateHelper.GetWeeksInGivenYear(2020);

      // This presumes that weeks start with Monday.
      // Week 1 is the 1st week of the year with a Thursday in it.
      public static int GetIso8601WeekOfYear(this 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);
      }

      //gets given year last week no
      public static int GetWeeksInGivenYear(int year)
      {
      DateTime lastDate = new DateTime(year, 12, 31);
      int lastWeek = GetIso8601WeekOfYear(lastDate);

      while (lastWeek == 1)
      {
      lastDate = lastDate.AddDays(-1);
      lastWeek = GetIso8601WeekOfYear(lastDate);

      }
      return lastWeek;
      }





      share|improve this answer






























        1














        I had issue when i assign 2018 to year parameter of other methods.
        I do not know maybe there are codes that work faster but i wrote following methods.



                //you can try like that 
        int weeks = DateHelper.GetWeeksInGivenYear(2018);
        int weeks = DateHelper.GetWeeksInGivenYear(2020);

        // This presumes that weeks start with Monday.
        // Week 1 is the 1st week of the year with a Thursday in it.
        public static int GetIso8601WeekOfYear(this 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);
        }

        //gets given year last week no
        public static int GetWeeksInGivenYear(int year)
        {
        DateTime lastDate = new DateTime(year, 12, 31);
        int lastWeek = GetIso8601WeekOfYear(lastDate);

        while (lastWeek == 1)
        {
        lastDate = lastDate.AddDays(-1);
        lastWeek = GetIso8601WeekOfYear(lastDate);

        }
        return lastWeek;
        }





        share|improve this answer




























          1












          1








          1







          I had issue when i assign 2018 to year parameter of other methods.
          I do not know maybe there are codes that work faster but i wrote following methods.



                  //you can try like that 
          int weeks = DateHelper.GetWeeksInGivenYear(2018);
          int weeks = DateHelper.GetWeeksInGivenYear(2020);

          // This presumes that weeks start with Monday.
          // Week 1 is the 1st week of the year with a Thursday in it.
          public static int GetIso8601WeekOfYear(this 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);
          }

          //gets given year last week no
          public static int GetWeeksInGivenYear(int year)
          {
          DateTime lastDate = new DateTime(year, 12, 31);
          int lastWeek = GetIso8601WeekOfYear(lastDate);

          while (lastWeek == 1)
          {
          lastDate = lastDate.AddDays(-1);
          lastWeek = GetIso8601WeekOfYear(lastDate);

          }
          return lastWeek;
          }





          share|improve this answer















          I had issue when i assign 2018 to year parameter of other methods.
          I do not know maybe there are codes that work faster but i wrote following methods.



                  //you can try like that 
          int weeks = DateHelper.GetWeeksInGivenYear(2018);
          int weeks = DateHelper.GetWeeksInGivenYear(2020);

          // This presumes that weeks start with Monday.
          // Week 1 is the 1st week of the year with a Thursday in it.
          public static int GetIso8601WeekOfYear(this 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);
          }

          //gets given year last week no
          public static int GetWeeksInGivenYear(int year)
          {
          DateTime lastDate = new DateTime(year, 12, 31);
          int lastWeek = GetIso8601WeekOfYear(lastDate);

          while (lastWeek == 1)
          {
          lastDate = lastDate.AddDays(-1);
          lastWeek = GetIso8601WeekOfYear(lastDate);

          }
          return lastWeek;
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Oct 15 '18 at 16:44

























          answered Aug 2 '18 at 13:00









          Murat Can OĞUZHANMurat Can OĞUZHAN

          304314




          304314























              1















              P.s.: in a year can be 52, 53, 54 weeks, not sure about 51




              1. If we will check With Calendar we will get results that we can have only 53 or 54 weeks.



              2. This is incorrect result (read the end of my answer)



              You can check it with the following app:



              using System;
              using System.Collections.Generic;
              using System.Drawing;
              using System.Globalization;
              using System.Linq;
              namespace TestConsoleApp
              {
              class Program
              {
              public static void Main(string args)
              {
              var b = CountWeeksForYearsRange(1, 4000);

              var c = b.Where(a => a.Value != 53).ToDictionary(a=>a.Key, a=>a.Value);
              }

              static DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
              static Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

              private static int CountWeeksInYear(int year)
              {
              DateTime date = new DateTime(year, 12, 31);
              return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
              }

              private static Dictionary<int,int> CountWeeksForYearsRange(int yearStart, int yearEnd)
              {
              Dictionary<int, int> rez = new Dictionary<int, int>();

              for (int i = yearStart; i <= yearEnd; i++)
              {
              rez.Add(i, CountWeeksInYear(i));
              }

              return rez;
              }
              }
              }


              and there will be only 53 and 54 values.



              This means that for faster work of method we can have pre-coded function for such situation.





              Years with not 53 weeks



              enter image description here





              Years with not 53 and not 54 weeks:



              enter image description here





              So in this case we can generate simple array of years that have 54 weeks from 0 to 4000 years:




              12,40,68,96,108,136,164,192,204,232,260,288,328,356,384,412,440,468,496,508,536,564,592,604,632,660,688,728,756,784,812,840,868,896,908,936,964,992,1004,1032,1060,1088,1128,1156,1184,1212,1240,1268,1296,1308,1336,1364,1392,1404,1432,1460,1488,1528,1556,1584,1612,1640,1668,1696,1708,1736,1764,1792,1804,1832,1860,1888,1928,1956,1984,2012,2040,2068,2096,2108,2136,2164,2192,2204,2232,2260,2288,2328,2356,2384,2412,2440,2468,2496,2508,2536,2564,2592,2604,2632,2660,2688,2728,2756,2784,2812,2840,2868,2896,2908,2936,2964,2992,3004,3032,3060,3088,3128,3156,3184,3212,3240,3268,3296,3308,3336,3364,3392,3404,3432,3460,3488,3528,3556,3584,3612,3640,3668,3696,3708,3736,3764,3792,3804,3832,3860,3888,3928,3956,3984




              And this is means that most optimized method will be:



              //Works only with 1-4000 years range
              public int CountWeeksInYearOptimized(int year)
              {
              return (_yearsWith54Weeks.IndexOf(year) == -1) ? 53 : 54;
              }
              private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
              204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
              592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
              964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
              1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
              1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
              1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
              2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
              2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
              3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
              3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
              3984 };


              or if you don't want to pre-calculated data:



                  DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
              Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

              private int CountWeeksInYear(int year)
              {
              DateTime date = new DateTime(year, 12, 31);
              return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
              }


              UPD: BUT! Looks like this is incorrect way.



              I don't know why so, but looks like Calendar saying incorrect number. And correct count of weeks is always on less on 1 week. You can check it manually:




              Let's calc days in the following years with Calendar:



              2011+2012+2013:



              53+54+53=160 weeks.



              But stop!



              (365+366+365)/7 = 157.




              So best way will be to do -1 to the value that will be shown by calendar



              Or to use the following fastest method:



              //Works only with 1-4000 years range
              public int CountWeeksInYearOptimized(int year)
              {
              return (_yearsWith54Weeks.IndexOf(year) == -1) ? 52 : 53;
              }
              private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
              204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
              592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
              964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
              1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
              1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
              1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
              2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
              2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
              3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
              3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
              3984 };





              share|improve this answer






























                1















                P.s.: in a year can be 52, 53, 54 weeks, not sure about 51




                1. If we will check With Calendar we will get results that we can have only 53 or 54 weeks.



                2. This is incorrect result (read the end of my answer)



                You can check it with the following app:



                using System;
                using System.Collections.Generic;
                using System.Drawing;
                using System.Globalization;
                using System.Linq;
                namespace TestConsoleApp
                {
                class Program
                {
                public static void Main(string args)
                {
                var b = CountWeeksForYearsRange(1, 4000);

                var c = b.Where(a => a.Value != 53).ToDictionary(a=>a.Key, a=>a.Value);
                }

                static DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
                static Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

                private static int CountWeeksInYear(int year)
                {
                DateTime date = new DateTime(year, 12, 31);
                return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
                }

                private static Dictionary<int,int> CountWeeksForYearsRange(int yearStart, int yearEnd)
                {
                Dictionary<int, int> rez = new Dictionary<int, int>();

                for (int i = yearStart; i <= yearEnd; i++)
                {
                rez.Add(i, CountWeeksInYear(i));
                }

                return rez;
                }
                }
                }


                and there will be only 53 and 54 values.



                This means that for faster work of method we can have pre-coded function for such situation.





                Years with not 53 weeks



                enter image description here





                Years with not 53 and not 54 weeks:



                enter image description here





                So in this case we can generate simple array of years that have 54 weeks from 0 to 4000 years:




                12,40,68,96,108,136,164,192,204,232,260,288,328,356,384,412,440,468,496,508,536,564,592,604,632,660,688,728,756,784,812,840,868,896,908,936,964,992,1004,1032,1060,1088,1128,1156,1184,1212,1240,1268,1296,1308,1336,1364,1392,1404,1432,1460,1488,1528,1556,1584,1612,1640,1668,1696,1708,1736,1764,1792,1804,1832,1860,1888,1928,1956,1984,2012,2040,2068,2096,2108,2136,2164,2192,2204,2232,2260,2288,2328,2356,2384,2412,2440,2468,2496,2508,2536,2564,2592,2604,2632,2660,2688,2728,2756,2784,2812,2840,2868,2896,2908,2936,2964,2992,3004,3032,3060,3088,3128,3156,3184,3212,3240,3268,3296,3308,3336,3364,3392,3404,3432,3460,3488,3528,3556,3584,3612,3640,3668,3696,3708,3736,3764,3792,3804,3832,3860,3888,3928,3956,3984




                And this is means that most optimized method will be:



                //Works only with 1-4000 years range
                public int CountWeeksInYearOptimized(int year)
                {
                return (_yearsWith54Weeks.IndexOf(year) == -1) ? 53 : 54;
                }
                private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
                204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
                592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
                964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
                1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
                1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
                1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
                2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
                2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
                3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
                3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
                3984 };


                or if you don't want to pre-calculated data:



                    DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
                Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

                private int CountWeeksInYear(int year)
                {
                DateTime date = new DateTime(year, 12, 31);
                return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
                }


                UPD: BUT! Looks like this is incorrect way.



                I don't know why so, but looks like Calendar saying incorrect number. And correct count of weeks is always on less on 1 week. You can check it manually:




                Let's calc days in the following years with Calendar:



                2011+2012+2013:



                53+54+53=160 weeks.



                But stop!



                (365+366+365)/7 = 157.




                So best way will be to do -1 to the value that will be shown by calendar



                Or to use the following fastest method:



                //Works only with 1-4000 years range
                public int CountWeeksInYearOptimized(int year)
                {
                return (_yearsWith54Weeks.IndexOf(year) == -1) ? 52 : 53;
                }
                private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
                204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
                592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
                964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
                1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
                1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
                1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
                2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
                2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
                3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
                3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
                3984 };





                share|improve this answer




























                  1












                  1








                  1








                  P.s.: in a year can be 52, 53, 54 weeks, not sure about 51




                  1. If we will check With Calendar we will get results that we can have only 53 or 54 weeks.



                  2. This is incorrect result (read the end of my answer)



                  You can check it with the following app:



                  using System;
                  using System.Collections.Generic;
                  using System.Drawing;
                  using System.Globalization;
                  using System.Linq;
                  namespace TestConsoleApp
                  {
                  class Program
                  {
                  public static void Main(string args)
                  {
                  var b = CountWeeksForYearsRange(1, 4000);

                  var c = b.Where(a => a.Value != 53).ToDictionary(a=>a.Key, a=>a.Value);
                  }

                  static DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
                  static Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

                  private static int CountWeeksInYear(int year)
                  {
                  DateTime date = new DateTime(year, 12, 31);
                  return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
                  }

                  private static Dictionary<int,int> CountWeeksForYearsRange(int yearStart, int yearEnd)
                  {
                  Dictionary<int, int> rez = new Dictionary<int, int>();

                  for (int i = yearStart; i <= yearEnd; i++)
                  {
                  rez.Add(i, CountWeeksInYear(i));
                  }

                  return rez;
                  }
                  }
                  }


                  and there will be only 53 and 54 values.



                  This means that for faster work of method we can have pre-coded function for such situation.





                  Years with not 53 weeks



                  enter image description here





                  Years with not 53 and not 54 weeks:



                  enter image description here





                  So in this case we can generate simple array of years that have 54 weeks from 0 to 4000 years:




                  12,40,68,96,108,136,164,192,204,232,260,288,328,356,384,412,440,468,496,508,536,564,592,604,632,660,688,728,756,784,812,840,868,896,908,936,964,992,1004,1032,1060,1088,1128,1156,1184,1212,1240,1268,1296,1308,1336,1364,1392,1404,1432,1460,1488,1528,1556,1584,1612,1640,1668,1696,1708,1736,1764,1792,1804,1832,1860,1888,1928,1956,1984,2012,2040,2068,2096,2108,2136,2164,2192,2204,2232,2260,2288,2328,2356,2384,2412,2440,2468,2496,2508,2536,2564,2592,2604,2632,2660,2688,2728,2756,2784,2812,2840,2868,2896,2908,2936,2964,2992,3004,3032,3060,3088,3128,3156,3184,3212,3240,3268,3296,3308,3336,3364,3392,3404,3432,3460,3488,3528,3556,3584,3612,3640,3668,3696,3708,3736,3764,3792,3804,3832,3860,3888,3928,3956,3984




                  And this is means that most optimized method will be:



                  //Works only with 1-4000 years range
                  public int CountWeeksInYearOptimized(int year)
                  {
                  return (_yearsWith54Weeks.IndexOf(year) == -1) ? 53 : 54;
                  }
                  private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
                  204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
                  592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
                  964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
                  1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
                  1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
                  1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
                  2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
                  2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
                  3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
                  3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
                  3984 };


                  or if you don't want to pre-calculated data:



                      DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
                  Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

                  private int CountWeeksInYear(int year)
                  {
                  DateTime date = new DateTime(year, 12, 31);
                  return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
                  }


                  UPD: BUT! Looks like this is incorrect way.



                  I don't know why so, but looks like Calendar saying incorrect number. And correct count of weeks is always on less on 1 week. You can check it manually:




                  Let's calc days in the following years with Calendar:



                  2011+2012+2013:



                  53+54+53=160 weeks.



                  But stop!



                  (365+366+365)/7 = 157.




                  So best way will be to do -1 to the value that will be shown by calendar



                  Or to use the following fastest method:



                  //Works only with 1-4000 years range
                  public int CountWeeksInYearOptimized(int year)
                  {
                  return (_yearsWith54Weeks.IndexOf(year) == -1) ? 52 : 53;
                  }
                  private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
                  204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
                  592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
                  964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
                  1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
                  1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
                  1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
                  2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
                  2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
                  3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
                  3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
                  3984 };





                  share|improve this answer
















                  P.s.: in a year can be 52, 53, 54 weeks, not sure about 51




                  1. If we will check With Calendar we will get results that we can have only 53 or 54 weeks.



                  2. This is incorrect result (read the end of my answer)



                  You can check it with the following app:



                  using System;
                  using System.Collections.Generic;
                  using System.Drawing;
                  using System.Globalization;
                  using System.Linq;
                  namespace TestConsoleApp
                  {
                  class Program
                  {
                  public static void Main(string args)
                  {
                  var b = CountWeeksForYearsRange(1, 4000);

                  var c = b.Where(a => a.Value != 53).ToDictionary(a=>a.Key, a=>a.Value);
                  }

                  static DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
                  static Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

                  private static int CountWeeksInYear(int year)
                  {
                  DateTime date = new DateTime(year, 12, 31);
                  return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
                  }

                  private static Dictionary<int,int> CountWeeksForYearsRange(int yearStart, int yearEnd)
                  {
                  Dictionary<int, int> rez = new Dictionary<int, int>();

                  for (int i = yearStart; i <= yearEnd; i++)
                  {
                  rez.Add(i, CountWeeksInYear(i));
                  }

                  return rez;
                  }
                  }
                  }


                  and there will be only 53 and 54 values.



                  This means that for faster work of method we can have pre-coded function for such situation.





                  Years with not 53 weeks



                  enter image description here





                  Years with not 53 and not 54 weeks:



                  enter image description here





                  So in this case we can generate simple array of years that have 54 weeks from 0 to 4000 years:




                  12,40,68,96,108,136,164,192,204,232,260,288,328,356,384,412,440,468,496,508,536,564,592,604,632,660,688,728,756,784,812,840,868,896,908,936,964,992,1004,1032,1060,1088,1128,1156,1184,1212,1240,1268,1296,1308,1336,1364,1392,1404,1432,1460,1488,1528,1556,1584,1612,1640,1668,1696,1708,1736,1764,1792,1804,1832,1860,1888,1928,1956,1984,2012,2040,2068,2096,2108,2136,2164,2192,2204,2232,2260,2288,2328,2356,2384,2412,2440,2468,2496,2508,2536,2564,2592,2604,2632,2660,2688,2728,2756,2784,2812,2840,2868,2896,2908,2936,2964,2992,3004,3032,3060,3088,3128,3156,3184,3212,3240,3268,3296,3308,3336,3364,3392,3404,3432,3460,3488,3528,3556,3584,3612,3640,3668,3696,3708,3736,3764,3792,3804,3832,3860,3888,3928,3956,3984




                  And this is means that most optimized method will be:



                  //Works only with 1-4000 years range
                  public int CountWeeksInYearOptimized(int year)
                  {
                  return (_yearsWith54Weeks.IndexOf(year) == -1) ? 53 : 54;
                  }
                  private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
                  204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
                  592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
                  964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
                  1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
                  1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
                  1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
                  2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
                  2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
                  3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
                  3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
                  3984 };


                  or if you don't want to pre-calculated data:



                      DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
                  Calendar calendar = DateTimeFormatInfo.CurrentInfo.Calendar;

                  private int CountWeeksInYear(int year)
                  {
                  DateTime date = new DateTime(year, 12, 31);
                  return calendar.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
                  }


                  UPD: BUT! Looks like this is incorrect way.



                  I don't know why so, but looks like Calendar saying incorrect number. And correct count of weeks is always on less on 1 week. You can check it manually:




                  Let's calc days in the following years with Calendar:



                  2011+2012+2013:



                  53+54+53=160 weeks.



                  But stop!



                  (365+366+365)/7 = 157.




                  So best way will be to do -1 to the value that will be shown by calendar



                  Or to use the following fastest method:



                  //Works only with 1-4000 years range
                  public int CountWeeksInYearOptimized(int year)
                  {
                  return (_yearsWith54Weeks.IndexOf(year) == -1) ? 52 : 53;
                  }
                  private List<int> _yearsWith54Weeks = new List<int> { 12, 40, 68, 96, 108, 136, 164, 192,
                  204, 232, 260, 288, 328, 356, 384, 412, 440, 468, 496, 508, 536, 564,
                  592, 604, 632, 660, 688, 728, 756, 784, 812, 840, 868, 896, 908, 936,
                  964, 992, 1004, 1032, 1060, 1088, 1128, 1156, 1184, 1212, 1240, 1268,
                  1296, 1308, 1336, 1364, 1392, 1404, 1432, 1460, 1488, 1528, 1556, 1584,
                  1612, 1640, 1668, 1696, 1708, 1736, 1764, 1792, 1804, 1832, 1860, 1888,
                  1928, 1956, 1984, 2012, 2040, 2068, 2096, 2108, 2136, 2164, 2192, 2204,
                  2468, 2496, 2508, 2536, 2564, 2592, 2604, 2632, 2660, 2688, 2728, 2756,
                  2784, 2812, 2840, 2868, 2896, 2908, 2936, 2964, 2992, 3004, 3032, 3060,
                  3088, 3128, 3156, 3184, 3212, 3240, 3268, 3296, 3308, 3336, 3364, 3392,
                  3668, 3696, 3708, 3736, 3764, 3792, 3804, 3832, 3860, 3888, 3928, 3956,
                  3984 };






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 18 at 6:23

























                  answered Jan 2 at 22:24









                  AndrewAndrew

                  2,32611426




                  2,32611426






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f17391073%2fhow-to-get-the-number-of-weeks-in-a-given-year%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      MongoDB - Not Authorized To Execute Command

                      in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

                      Npm cannot find a required file even through it is in the searched directory