Как правильно настроить NodaTime IWeekYearRule вручную? - PullRequest
0 голосов
/ 14 января 2019

Я обертываю 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
...