How to Get the number of weeks in a given year
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
|
show 12 more comments
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
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
|
show 12 more comments
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
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
c# week-number
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
|
show 12 more comments
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
|
show 12 more comments
3 Answers
3
active
oldest
votes
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...)
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
|
show 1 more comment
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;
}
add a comment |
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
Years with not 53 and not 54 weeks:
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 };
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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...)
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
|
show 1 more comment
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...)
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
|
show 1 more comment
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...)
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...)
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
|
show 1 more comment
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
|
show 1 more comment
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;
}
add a comment |
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;
}
add a comment |
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;
}
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;
}
edited Oct 15 '18 at 16:44
answered Aug 2 '18 at 13:00


Murat Can OĞUZHANMurat Can OĞUZHAN
304314
304314
add a comment |
add a comment |
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
Years with not 53 and not 54 weeks:
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 };
add a comment |
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
Years with not 53 and not 54 weeks:
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 };
add a comment |
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
Years with not 53 and not 54 weeks:
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 };
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
Years with not 53 and not 54 weeks:
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 };
edited Jan 18 at 6:23
answered Jan 2 at 22:24


AndrewAndrew
2,32611426
2,32611426
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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