namespace System.Globalization { public partial class Calendar { public static class ISOWeek { private static int GetWeek(DateTime time) { var week = GetWeekNumber(time); if (week < 1) { // The given date belongs to the preceding (week-based) year. return GetWeeksInYear(time.Year - 1); } if (week > GetWeeksInYear(time.Year)) { // The date is actually in week 1 of the following year. return 1; } return week; } private static int GetYear(DateTime time) { var week = GetWeekNumber(time); if (week < 1) { // The given date belongs to the preceding (week-based) year. return time.Year - 1; } if (week > GetWeeksInYear(time.Year)) { // The date is actually in week 1 of the following year. return time.Year + 1; } return time.Year; } public static DateTime GetYearStart(int year) { // Gets Monday in the first week of the year. return GetDate(year, 1, DayOfWeek.Monday); } public static DateTime GetYearEnd(int year) { // Gets Sunday in the last week of the year. return GetDate(year, GetWeeksInYear(year), DayOfWeek.Sunday); } public static DateTime GetDate(int year, int week, DayOfWeek dayOfWeek) { var jan4DayOfWeek = new DateTime(year, 1, 4).DayOfWeek; var dayOfYear = (week * 7) + GetWeekday(dayOfWeek) - (GetWeekday(jan4DayOfWeek) + 3); return new DateTime(year, 1, 1).AddDays(dayOfYear - 1); } public static int GetWeeksInYear(int year) { int P(int y) => (y + (y / 4) - (y / 100) + (y / 400)) % 7; return P(year) == 4 || P(year - 1) == 3 ? 53 : 52; } private static int GetWeekNumber(DateTime time) { return (time.DayOfYear - GetWeekday(time.DayOfWeek) + 10) / 7; } private static int GetWeekday(DayOfWeek dayOfWeek) { return ((int) dayOfWeek + 6) % 7 + 1; } } } }