VB.NET DatetimePicker - неверный номер недели

У меня проблема с расширенным средством выбора даты и времени vbnet. Когда элемент переходит к новому году (2016), номер недели, отображаемый слева, неверен.

Неверный номер недели

У меня есть «datetimepicker», который не является компонентом по умолчанию, он был загружен здесь: http://www.codeproject.com/Articles/17063/ExtendedDateTimePicker-control-with-week-numbers

Я не понимаю, почему календарь переходит с 53 на 2, а не с 53 на 1.

Может у кого-то из вас такая же ошибка. Спасибо за ваше время.


person user2839159    schedule 03.11.2015    source источник
comment
Возможно, вам следует задать этот вопрос на доске обсуждений собственной статьи, поскольку это не компонент по умолчанию, а сторонняя разработка.   -  person ɐsɹǝʌ ǝɔıʌ    schedule 03.11.2015
comment
Я пытаюсь, но это старая статья. Насколько я понял, неправильный формат даты. Может это не 8601   -  person user2839159    schedule 03.11.2015
comment
NET не соответствует стандарту ISO8601, но есть несколько вариантов календаря, чтобы получить что-то похожее (и всего 1-2 строки кода для преобразования или эмуляции). Код не вычисляет WOY, а просто отключает PInvoke, чтобы заставить NET сделать это. Насколько я помню, первая неделя года - это четверг. Поскольку 01.01.2016 — это четверг, я думаю, что если вы перейдете к следующему месяцу, то 1-2-3 января будет первой неделей 2016 года.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 03.11.2015
comment
Хорошо спасибо. Я должен добавить это прямо в элемент управления?   -  person user2839159    schedule 02.03.2016
comment
Я единственный, кто думает, что этот контроль работает идеально? Неделя 53 — 28, 29, 30, 31 декабря. 1 неделя - 1,2,3 января. Это неделя 53/1, поэтому нет ничего плохого в том, чтобы показать неделю 2 на следующей неделе.   -  person Claudius    schedule 04.03.2016


Ответы (2)


I don't understand why the calendar pass from 53 to 2 and not 53 to 1

Это в значительной степени работает, как и ожидалось. При подсчете недель эти первые 3 дня 2016 года считаются первой неделей 2016 года.

Обратите внимание, что элемент управления не делает ничего, связанного с календарем или дисплеем. Это просто изменение стиля отображения окна календаря, предоставляемого Windows. Код, показанный на странице CP, — это все, что есть, и в основном он просто устанавливает флаг стиля, чтобы указать Windows добавить номера недель:

style = style | MCS_WEEKNUMBERS;

Запись MSDN для него указывает:

Неделя 1 определяется как первая неделя, которая содержит не менее четырех дней.

Поскольку 1-3 января — это не 4 дня, может показаться, что это либо ошибка, либо используется другой календарь, либо MSDN устарел.


Из комментариев:

From what i understood, what's wrong is "date format". Maybe it's not a 8601

Нет, это нечто большее: ISO8601 — это другой календарь, который не реализован ни в Windows, ни в NET. Википедия отмечает:

Первая неделя года — это неделя, которая содержит первый четверг года (и, следовательно, всегда содержит 4 января). Таким образом, нумерация недель по ISO немного отличается от григорианской для некоторых дней, близких к 1 января.

Это то, что вы видите в раскрывающемся списке календаря.

Альтернативный

Но неделю года ISO8601 легко рассчитать:

Начните с кода для GetISOWeekOfYear() из мой ответ на очень похожий вопрос. Вы можете использовать это для отображения недели года ISO8601 для выбранной даты в метке или чем-то рядом с DTP.

Выведите номера первой и последней недель с 2011 по 2021 год:

Dim cal As Calendar = CultureInfo.CurrentCulture.DateTimeFormat.Calendar
For n As Int32 = 2011 To 2017       '2021
    dt = New DateTime(n, 12, 21)
    Console.WriteLine(" ***** {0} *****", n)
    For j = 0 To 3
        Dim NetWk = cal.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, firstD)
        Console.WriteLine("Invariant Date: {0} ISO #:{1:00}  NET #:{2:00}",
                          dt.ToString("MM/dd/yyyy"), GetISOWeekOfYear(dt), NetWk)
        dt = dt.AddDays(7)
    Next
Next

Результат за 2015/2016 часть:

***** 2015 *****
Дата инварианта: 21.12.2015 ISO #:52 NET #:52
Дата инварианта: 28.12.2015 ISO #:53 NET #:53< br> Дата инварианта: 04.01.2016 ISO #:01 NET #:02
Дата инварианта: 11.01.2016 ISO #:02 NET #:03
***** 2016 **** *
Дата изменения: 21.12.2016 ISO #:51 NET #:52
Дата изменения: 28.12.2016 ISO #:52 NET #:53
Дата изменения: 04.01.2017 ISO #:01 NET #:01
Инвариант Дата: 11.01.2017 ISO #:02 NET #:02

Если вы не хотите написать свой собственный элемент управления с нуля или лицензировать тот, который может быть установлен для другого календаря (и имеет определение для ISO8601), это может быть лучшим, что вы можете сделать.

Итог: номер недели не является неправильным. Он использует другой календарь, чем вы ожидаете / хотите.


Использованная литература:

person Ňɏssa Pøngjǣrdenlarp    schedule 03.03.2016
comment
Вы должны использовать формат даты ISO (yyyy-MM-dd) в SO, чтобы избежать региональной путаницы. - person Enigmativity; 05.03.2016

Управление работает нормально.

Когда год меняется в течение последних нескольких дней года, это 53-я неделя, но это не полная неделя. Точно так же первые несколько дней года относятся к неделе 1, но система управления использует настройку «первый день недели» системы, чтобы определить, когда начинается неделя 2, поэтому первая неделя года может иметь любое место. от 1 до 7 дней в нем.

Это означает, что изображение, которое вы показали, показывает неделю 53, потому что вы находитесь в декабре, и неделю 2, потому что 2-я неделя января начинается 4-го числа.

Если вы перейдете к январю, будет отображаться неделя 1 для строки, начинающейся 28 декабря.

Суть в том, что в первой неделе января всего 3 дня.

Это просто нормальное и правильное поведение этого элемента управления.

person Enigmativity    schedule 05.03.2016