Reputation: 800
I'm trying to get the number of ISO weeks in given year/leap year. I saw that .Net Core 3.0 have ISOWeek.GetWeeksInYear
class, but we're running .Net Core 2.2.1... and it's not possible to update at the moment...
I've tried this:
var cultInfo = CultureInfo.CurrentCulture;
var lastDayOfYear = new DateTime(2019, 12, 31);
var numberOfWeeks = cultInfo.Calendar.GetWeekOfYear(
lastDayOfYear,
cultInfo.DateTimeFormat.CalendarWeekRule,
DayOfWeek.Monday);
With 2019
it returns 53
, it's not correct by the result I wanted (52
). And if I change the date to 2020
it is 53
, which is correct, but yeah, not by ISO which is what I want.
Thanks in advance.
Upvotes: 1
Views: 503
Reputation: 23228
You can have a look at ISOWeek
sources and implement this method by yourself (since you can't target .NET Core 3.x)
private const int WeeksInLongYear = 53;
private const int WeeksInShortYear = 52;
public static int GetWeeksInYear(int year)
{
if (year < 1 || year > 9999)
{
throw new ArgumentOutOfRangeException(nameof(year));
}
static int P(int y) => (y + (y / 4) - (y / 100) + (y / 400)) % 7;
if (P(year) == 4 || P(year - 1) == 3)
{
return WeeksInLongYear;
}
return WeeksInShortYear;
}
Then use it
var weeks = GetWeeksInYear(2019); //returns 52
weeks = GetWeeksInYear(2020); //returns 53
Please, keep in mind, that static local functions are supported starting from C# 8, so you should switch to this version or rewrite a code a little bit
Upvotes: 3
Reputation: 186668
A year contains 53
ISO weeks if and only if it contains 53
Thursdays; so in order to return 53
a year must either
Thursday
Thursday
or Wednesday
Code:
public static int GetWeeksInYear(int year) {
if (year < DateTime.MinValue.Year || year > DateTime.MaxValue.Year)
throw new ArgumentOutOfRangeException(nameof(year));
var dw = new DateTime(year, 1, 1).DayOfWeek;
return (dw == DayOfWeek.Thursday) ||
(dw == DayOfWeek.Wednesday) && DateTime.IsLeapYear(year)
? 53
: 52;
}
Demo:
var report = string.Join(Environment.NewLine, Enumerable
.Range(1990, 2020 - 1990 + 1)
.Select(year => $"{year} : {GetWeeksInYear(year)}"));
Console.Write(report);
Outcome:
1990 : 52
1991 : 52
1992 : 53
1993 : 52
1994 : 52
1995 : 52
1996 : 52
1997 : 52
1998 : 53
1999 : 52
2000 : 52
2001 : 52
2002 : 52
2003 : 52
2004 : 53
2005 : 52
2006 : 52
2007 : 52
2008 : 52
2009 : 53
2010 : 52
2011 : 52
2012 : 52
2013 : 52
2014 : 52
2015 : 53
2016 : 52
2017 : 52
2018 : 52
2019 : 52
2020 : 53
Upvotes: 2