Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VB.NET DatetimePicker - Wrong week number

I have an issue with my vbnet extented datetime picker. When the element pass to new year (2016), the week number displayed on the left is wrong.

Wrong week number

I have a "datetimepicker" which is not the default component, it was downloaded here : http://www.codeproject.com/Articles/17063/ExtendedDateTimePicker-control-with-week-numbers

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

Maybe one of you has the same error. Thanks for your time.

like image 312
user2839159 Avatar asked Sep 27 '22 07:09

user2839159


2 Answers

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

It is pretty much working as expected. The way it is counting weeks, those first 3 days of 2016 count as the first week of 2016.

Note that the control doesnt do anything calendar or display related. It is simply changing the display style of the calendar window provided by Windows. The code seen on the CP page is all there is and mainly it just sets a style flag to tell Windows to add the week numbers:

style = style | MCS_WEEKNUMBERS;

The MSDN entry for it indicates:

Week 1 is defined as the first week that contains at least four days.

Since Jan 1-3 is not 4 days, it would seem that there is either an error, a different calendar being used or MSDN is out of date.


From comments:

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

No, it is more than that: ISO8601 is a different calendar which neither Windows nor NET implements. Wikipedia notes:

The first week of a year is the week that contains the first Thursday of the year (and, hence, always contains 4 January). ISO week year numbering therefore slightly deviates from the Gregorian for some days close to 1 January.

This is what you see in the calendar drop down.

Alternative

But the ISO8601 Week Of Year is easy to calculate:

Start with the code for GetISOWeekOfYear() from my answer to a very similar question. You can use that to display the ISO8601 week of year for the selected date in a label or something next to the DTP.

Print the first and last week numbers for 2011 To 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

The result for 2015/2016 portion:

***** 2015 *****
Invariant Date: 12/21/2015 ISO #:52 NET #:52
Invariant Date: 12/28/2015 ISO #:53 NET #:53
Invariant Date: 01/04/2016 ISO #:01 NET #:02
Invariant Date: 01/11/2016 ISO #:02 NET #:03
***** 2016 *****
Invariant Date: 12/21/2016 ISO #:51 NET #:52
Invariant Date: 12/28/2016 ISO #:52 NET #:53
Invariant Date: 01/04/2017 ISO #:01 NET #:01
Invariant Date: 01/11/2017 ISO #:02 NET #:02

Unless you are willing to write your own control from scratch or license one which can be set to a different calendar (and has a definition for ISO8601), that may be the best you can do.

The Bottomline: The Week number is not wrong. It using a different calendar than you expect/want.


References:

  • Get or convert NET GetWeekOfYear() to ISO week
  • MSDN: Month Calendar Control Styles
  • DateTimePicker in Reference Source
like image 138
Ňɏssa Pøngjǣrdenlarp Avatar answered Sep 30 '22 08:09

Ňɏssa Pøngjǣrdenlarp


The control is working fine.

When the year changes over the final few days of the year are in week 53 - but it's not a full week. Similarly the first few days of the year are in week 1, but the control takes the system's "first day of the week" setting to determine when week 2 begins - so it is possible for the first week of the year to have any where from 1 to 7 days in it.

This means that the image you've shown is showing Week 53 because you're in December and Week 2 because the 2nd week of January does start on the 4th.

If you navigate to January it would display week 1 for the row starting on December 28.

The bottom-line is that the first week in January only has 3 days in it.

This is just the normal and correct behaviour of this control.

like image 22
Enigmativity Avatar answered Sep 30 '22 08:09

Enigmativity