P.s.:一年中可能是 52、53、54 周,不确定是 51 周
1.如果我们使用日历检查,我们将得到只有 53 或 54 周的结果。
2。这是不正确的结果(阅读我答案的结尾)
您可以通过以下应用查看:
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;
}
}
}
只有 53 和 54 个值。
这意味着为了更快地工作,我们可以为这种情况预先编码函数。
没有 53 周的年份
不是 53 周也不是 54 周的年份:
所以在这种情况下,我们可以生成简单的年份数组,从 0 年到 4000 年有 54 周:
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
这意味着最优化的方法是:
//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 };
或者如果您不想预先计算数据:
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:但是!看起来这是不正确的方式。
我不知道为什么会这样,但看起来日历显示的数字不正确。正确的周数总是少于 1 周。您可以手动检查:
让我们用日历计算接下来几年的天数:
2011+2012+2013:
53+54+53=160 周。
但是停下来!
(365+366+365)/7 = 157.
所以最好的方法是对日历显示的值做-1
或者使用以下最快的方法:
//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 };