Я много гуглил и нашел много решений, но ни одно из них не дает мне правильный номер недели на 2012-12-31. Даже пример на MSDN ( ссылка ) терпит неудачу.
2012-12-31 - понедельник, поэтому это должна быть неделя 1, но каждый метод, который я пробовал, дает мне 53. Вот некоторые из методов, которые я пробовал:
Из библиотеки MDSN:
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;
return cal.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
Решение 2:
return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
Решение 3:
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;
Обновить
Следующий метод фактически возвращает 1, когда дата 2012-12-31. Другими словами, моя проблема заключалась в том, что мои методы не соответствовали стандарту ISO-8601.
// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
// Seriously cheat. If its Monday, Tuesday or Wednesday, then it'll
// be the same week# as whatever Thursday, Friday or Saturday are,
// and we always get those right
DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
time = time.AddDays(3);
}
// Return the week of our adjusted day
return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
Ответы:
Как отмечено на этой странице MSDN, существует небольшая разница между неделей нумерации ISO8601 и неделей .Net.
Вы можете обратиться к этой статье в блоге MSDN для лучшего объяснения: « Формат недели года ISO 8601 в Microsoft .Net »
Проще говоря, .Net позволяет разделять недели по годам, а стандарт ISO - нет. В статье также есть простая функция для получения правильного номера недели ISO 8601 для последней недели года.
Обновление Следующий метод на самом деле возвращает 1,
2012-12-31
что является правильным в ISO 8601 (например, Германия).источник
Может быть более 52 недель в году. Каждый год имеет 52 полных недели + 1 или +2 (високосный год) дополнительных дней. Они компенсируют 53-ю неделю.
Таким образом, на каждый год у вас есть хотя бы один дополнительный день. Два за високосные годы. Эти дополнительные дни считаются отдельными неделями?
Сколько недель действительно зависит от начального дня вашей недели. Давайте рассмотрим это на 2012 год.
Проверьте текущие настройки культуры, чтобы увидеть, что она использует в качестве первого дня недели.
Как видите, нормально получить 53 в результате.
Можно даже провести 54-ю неделю. Бывает каждые 28 лет, когда 1 января и 31 декабря рассматриваются как отдельные недели. Это должен быть високосный год тоже.
Например, в 2000 году было 54 недели. 1 января (суббота) был первым днем недели, а 31 декабря (солнце) - вторым днем недели.
Выходит: Год: 2012 Неделя: 54
Измените CalendarWeekRule в приведенном выше примере на FirstFullWeek или FirstFourDayWeek, и вы вернетесь 53. Давайте оставим стартовый день в понедельник, так как мы имеем дело с Германией.
Таким образом, неделя 53 начинается в понедельник 2012-12-31, длится один день, а затем останавливается.
53 является правильным ответом. Измените Культуру на Германию, если хотите попробовать.
источник
Это способ:
Наиболее важным является
CalendarWeekRule
параметр.Смотрите здесь: https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=IT-IT&k=k(System.Globalization.CalendarWeekRule);k(TargetFrameworkMoniker-.NETFramework
источник
Хорошие новости! Добавление запроса на добавление
System.Globalization.ISOWeek
в .NET Core было только что объединено и в настоящее время запланировано на выпуск 3.0. Надеемся, что он распространится на другие платформы .NET в недалеком будущем.Тип имеет следующую подпись, которая должна охватывать большинство потребностей недели ISO :
Вы можете найти исходный код здесь .
ОБНОВЛЕНИЕ : Эти API также были включены в версию 2.1 стандарта .NET .
источник
Поскольку, по-видимому, не существует .Net-культуры, которая выдает правильный номер недели ISO-8601, я бы предпочел полностью обойти определение встроенной недели и выполнить расчет вручную, вместо того, чтобы пытаться исправить частично правильное значение. результат.
В итоге я выбрал следующий метод расширения:
Прежде всего,
((int)date.DayOfWeek + 6) % 7)
определяет номер дня недели, 0 = понедельник, 6 = воскресенье.date.AddDays(-((int)date.DayOfWeek + 6) % 7)
определяет дату понедельника, предшествующего запрошенному номеру недели.Три дня спустя - целевой четверг, который определяет год недели.
Если вы поделите (на основе нуля) число дней в году на семь (округление вниз), вы получите номер недели (на основе нуля) в году.
В c # результаты вычисления целых чисел неявно округляются.
источник
Ticks
это число приращений в 100 наносекунд с 1 января 0001 года. Учитывая, что в дне 86 400 секунд, мы можем написать:var thursday = date.AddDays(3 - date.Ticks / 86400 / 10_000_000 % 7); return (thursday.DayOfYear - 1) / 7 + 1;
В .NET 3.0 и более поздних версиях вы можете использовать
ISOWeek.GetWeekOfDate
-Method .Обратите внимание, что год в формате числа год + неделя может отличаться от года из-
DateTime
за недель, пересекающих границу года.источник
C # в порт Powershell из приведенного выше кода из il_guru :
источник
Самый простой способ определить стиль номера недели ISO 8601 с помощью c # и класса DateTime.
Спросите: четверг года - это четверг этой недели. Ответ равен номеру требуемой недели.
источник
Это хорошо работает как для культур США и России. ISO 8601 также будет правильным, потому что русская неделя начинается в понедельник.
источник
Вот расширенная версия и обнуляемая версия ответа il_guru .
Расширение:
Nullable:
Обычаи:
источник
Вопрос в том, как определить, будет ли неделя в 2012 году или в 2013 году. Я полагаю, что вы предполагаете, что, поскольку в 2013 году 6 дней недели, эта неделя должна быть отмечена как первая неделя 2013 года.
Не уверен, что это правильный путь. Эта неделя началась в 2012 году (в понедельник 31 декабря), поэтому она должна быть помечена как последняя неделя 2012 года, следовательно, она должна быть 53-й 2012 года. Первая неделя 2013 года должна начаться в понедельник 7-го.
Теперь вы можете обрабатывать конкретный случай крайних недель (первой и последней недели года), используя информацию о дне недели. Все зависит от вашей логики.
источник
источник
Основываясь на ответе il_guru, я создал эту версию для своих нужд, которая также возвращает компонент year.
источник
Эти два метода помогут, предполагая, что наша неделя начинается в понедельник
источник
Год имеет 52 недели и 1 день или 2 в случае коленного года (52 x 7 = 364). 2012-12-31 - это 53-я неделя, неделя, на которую уйдет всего 2 дня, потому что 2012 год - это круговой год.
источник
источник