Я обертываю NodaTime для использования в нашем программном обеспечении, и чтобы быть уверенным в будущем, я решил настроить IWeekYearRule в соответствии с Bcl DateTimeFormat, например:
var culture = CultureInfo.CurrentCulture;
var weekRule = WeekYearRules.FromCalendarWeekRule(
culture.DateTimeFormat.CalendarWeekRule,
culture.DateTimeFormat.FirstDayOfWeek);
Здесь, в Норвегии, мы придерживаемся следующих настроек:
CalendarWeekRule.FirstFourDayWeek
DayOfWeek.Monday
Однако, к моему большому удивлению, когда я проверил номер недели следующих двух дат, kalender.no не согласен:
2018-12-31: week 53 of 2018 (kalender.no says week 1 [implied: of 2019])
2019-01-01: week 1 of 2019 (kalender.no agrees here)
Однако, если я использую WeekYearRules.Iso, они оба возвращают «неделю 1 из 2019», которая является правильной.
У меня есть куча вопросов, но давайте сосредоточимся на самом ближайшем:
Как я могу написать код для "будущей" этой части библиотеки, чтобы, когда мы начнем внедрять программное обеспечение в другие части мира, оно будет правильно рассчитывать номера недель из коробки, в соответствии с местная культура?
Или это просто невозможно, потому что информация о культуре этого не содержит?
Вот пример LINQPad , который демонстрирует поведение NodaTime (извините, что не включил [mcve] для начала):
void Main()
{
"-------------- ISO --------------".Dump();
Test(WeekYearRules.Iso);
"-------------- BCL --------------".Dump();
Test(WeekYearRules.FromCalendarWeekRule(CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday));
}
public static void Test(IWeekYearRule rule)
{
var date = new LocalDate(2018, 12, 31);
$"{date}, {rule.GetWeekOfWeekYear(date)} in {rule.GetWeekYear(date)}".Dump();
date = new LocalDate(2019, 1, 1);
$"{date}, {rule.GetWeekOfWeekYear(date)} in {rule.GetWeekYear(date)}".Dump();
}
Вывод:
-------------- ISO --------------
mandag 31. desember 2018, 1 in 2019
tirsdag 1. januar 2019, 1 in 2019
-------------- BCL --------------
mandag 31. desember 2018, 53 in 2018
tirsdag 1. januar 2019, 1 in 2019
(и чтобы было ясно, выход ISO является правильным для Норвегии)
Это NodaTime 2.4.4, Windows 10, .NET 4.7.2.
А вот пример LINQPad без использования NodaTime:
void Main()
{
var culture = CultureInfo.GetCultureInfo("nb-NO");
var calendarWeekRule = culture.DateTimeFormat.CalendarWeekRule.Dump();
var firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek.Dump();
var date = new DateTime(2018, 12, 31);
$"{date.DayOfWeek} {date}, week {culture.Calendar.GetWeekOfYear(date, calendarWeekRule, firstDayOfWeek)}".Dump();
date = new DateTime(2019, 1, 1);
$"{date.DayOfWeek} {date}, week {culture.Calendar.GetWeekOfYear(date, calendarWeekRule, firstDayOfWeek)}".Dump();
}
Выход:
FirstFourDayWeek
Monday
Monday 31.12.2018 00.00.00, week 53
Tuesday 01.01.2019 00.00.00, week 1
Понедельник наступает на той же неделе, что и 1-я неделя 2019 года, и здесь, в Норвегии, считается 1-й неделей в 2019 году, поэтому первая из двух дат должна была действительно быть:
Monday 31.12.2018 00.00.00, week 1