Получить количество недель ISO в данном году в C# - PullRequest
1 голос
/ 18 февраля 2020

Я пытаюсь получить количество ISO недель с в данном году / високосном году. Я видел, что . Net Core 3.0 имеет класс ISOWeek.GetWeeksInYear, но мы работаем. Net Core 2.2.1 ... и обновление невозможно момент ...

Я пробовал это:

var cultInfo = CultureInfo.CurrentCulture;
var lastDayOfYear = new DateTime(2019, 12, 31);
var numberOfWeeks = cultInfo.Calendar.GetWeekOfYear(
                                    lastDayOfYear,
                                    cultInfo.DateTimeFormat.CalendarWeekRule,
                                    DayOfWeek.Monday);

С 2019 возвращает 53, не правильно желаемым результатом (52). И если я изменю дату на 2020, это будет 53, что является правильным , но да, не по ISO, что я и хочу.

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 18 февраля 2020

Вы можете взглянуть на ISOWeek источников и реализовать этот метод самостоятельно (поскольку вы не можете нацелиться. 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;
}

Затем используйте его

var weeks = GetWeeksInYear(2019); //returns 52
weeks = GetWeeksInYear(2020); //returns 53

Имейте в виду, что stati c локальные функции поддерживаются начиная с C# 8, поэтому вам следует перейти на эту версию или переписать код немного

2 голосов
/ 18 февраля 2020

Год содержит 53 ISO недель , если и только если он содержит 53 четверг ; поэтому для возврата 53 год должен либо

  1. начинаться с Thursday
  2. быть високосным годом и начинаться либо с Thursday, либо Wednesday

Код:

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;
}

Демо:

  var report = string.Join(Environment.NewLine, Enumerable
    .Range(1990, 2020 - 1990 + 1)
    .Select(year => $"{year} : {GetWeeksInYear(year)}"));

  Console.Write(report);

Результат :

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
...