DateTime: No week 1 in 2021?

I have a web app (API 1.0, so Xojo 2019r3.2) with a custom calendar control based on DateTime (Yes, I know a plug in would be much wiser in terms of performance. For reasons unknown to me by customer request).

I was just made aware that there is no week 1 when you cross next new year.
Could it be that DateTime gets WeekOfYear wrong?

The quick and dirty code that builds my date time array:

Var firstDayOfMonth As  DateTime = today.firstDayOfMonth
Var FirstWeekDay As Integer = firstDayOfMonth.GermanDayOfWeek
Var LeadingMonthDays As Integer = FirstWeekDay-1
Var lastDayOfMonth As DateTime = Today.LastDayOfMonth
Var LastWeekDay As Integer = lastDayOfMonth.GermanDayOfWeek
Var TrailingMonthDays As Integer = 7 - LastWeekDay
DisplayDays.ResizeTo(LeadingMonthDays-1)
Var currentdatadate As New DateTime(firstDayOfMonth)
For q  = LeadingMonthDays -1 DownTo 0
  currentdatadate = currentdatadate-New DateInterval(0, 0, 1)
  DisplayDays(q) = New DateTime(currentdatadate)
Next
currentdatadate = New DateTime(firstDayOfMonth)
DisplayDays.AddRow New date(currentdatadate)
For q = 2 To lastDayOfMonth.Day
  currentdatadate = currentdatadate+ New DateInterval(0,0,1)
  DisplayDays.AddRow New date(currentdatadate)
Next
For q = DisplayDays.LastRowIndex To 40
  currentdatadate = currentdatadate+ New DateInterval(0,0,1)
  DisplayDays.AddRow New date(currentdatadate)
Next

(So basically I just build a days array, starting with Monday of the first or leading week, adding a timeinterval of one day for each item which should be safe I guess.)
GermanDayOfWeek simply shifts dayOfWeek by one because our weeks start with Monday.
And part of the control’s paint event:

If ShowWeekNumbers Then // Wochennummern
  Displaywidth = Displaywidth - 35
  LeftBorder = 36
  g.DrawLine 35,TopBorder,35,g.Height
  For rows As Integer = 0 To If (Me.ViewMode = ViewModes.Monthly, 6, 0)
    g.DrawLine 1,TopBorder+rows*cellheight, 36, topborder+rows*cellheight
    If rows < 6 Then
      Var currentdate As DateTime = DisplayDays(rows*7)
      Var week As Integer = currentdate.WeekOfYear
      g.TextFont = "Noto Sans"
      g.TextSize = 12
      g.DrawString week.ToString("00"), 8, TopBorder+rows*Cellheight+17
    End If
  Next
End If

That bug is not based on crossing the year. February 2021 starts with week 6 which is wrong.
Is this a known bug? Was it fixed?
(I will have to resort to a workaround anyway and think that checking for an offset – if Jan 1st of the current year is not in week one, subtract 1 – will be sufficient, but I blushed a bit. Or any mistake on my side visible?)

From what I understand January 1st will always be week 1 but January 2nd could be the start of week 2. From the docs:

Notes

The first week is numbered 1. The first week may be incomplete. If January 1 falls on a Saturday, then the next day is in week 2.

That would be logical in mathematical terms, but not in calendaric ones – at least not for Germany.
For us, week one starts on January 4th.

After some more research: The first week of the year is that one with the first Thursday in it.
So WeekOfYear is quite misleading in terms of ISO-compatible calendar calculations. But can be easily fixed.
(And, as you said, ok by the docs. But not for more internationally.)

I can’t help you with that, I have never seen Week of Year being used in Mexico so I don’t know if there is an international standard on how to use it.

1 Like

I just battled the topic of ISO week numbers where Monday is being recognized as 1st day of Week and where 1st Thursday in January of a given year declares the whole week as a first one and so on… it uses old API but works :wink:

Public Function ISOWeekNumber(dt as date) as integer
// nr of week for given date
// as based od ISO 8601 date and time standard
// where Monday is 1st day of week

var dow2,dow,woy,woy2 as integer
dow=dt.DayOfWeek-1
if dow=0 then dow=7
woy=Floor((10+dt.DayOfYear-dow)/7)
if woy=0 then
var dp as new date (dt.Year-1,12,31)
dow2=dp.DayOfWeek-1
if dow2=0 then dow2=7
woy=Floor((10+dp.DayOfYear-dow2)/7)
else
if woy=53 then
var dp as new date (dt.Year+1,1,1)
dow2=dp.DayOfWeek-1
if dow2=0 then dow2=7
if dow2<5 then woy=1
end if
end if
Return woy

End Function

In my application KW13, I use “ncal -w 1 2021” to get the calendar week numbers.

ncal -w 1 2021
Januar 2021
Mo 4 11 18 25
Di 5 12 19 26
Mi 6 13 20 27
Do 7 14 21 28
Fr 1 8 15 22 29
Sa 2 9 16 23 30
So 3 10 17 24 31
KW 53 1 2 3 4

I knew about ncal under MacOS but what about Windows…? hence I did it on my own.

1 Like

…there are more problems:

  • the last days of previous year can be in 1st week
  • or, first days of actual year can be in last week of previous year.

Is this an OS bug or a Xojo one?
If the OS always uses the same rules regardless of the chosen locale settings, the only doable fix is in code (which is just a workaround).
But if the OS has an API to return the correct value (which Xojo doesn’t use) or otherwise a bug in Xojo, then it should just be fixed there and the standard method would work.

XOJO uses US approach - 1st day of January declares the whole week as 1st week of year - and Sunday is first day of a week. Easy. Then comes ISO norm… such week can be addressed the 1st week of actual year and - in the same time, the last week for previous year. So for 2020-12-31 it can be 53rd week and at the same time, 2021-01-01 can be 1st week. 53rd and 1st points to the same week which is avoidable using ISO approach.

1 Like

What do you mean by this? Your code seems to work perfectly fine :muscle: if we replace date by datetime, at least as far as I could see in a quick test.

1 Like

sure, it could be datetime instead of date :smiley:

1 Like

If you use this, the week number is always 2.

var dd as DateTime
dd = DateTime.now(New TimeZone(“Europe/Berlin”))

Normally, I would expect that specifying a time zone would also take the correct values for the calendar week.

For all of us outside of the US, it’s the opposite… We have our usual everyday rules. Then comes US norm which Xojo uses.

Don’t think it’s used here in the UK either.

normally you don’t pay attention to week numbers but when it comes to i.e. production planning, to synchronize deliveries of raw materials etc. in EU - they all use week numbers to confirm :confused:

1 Like

same for financial reporting and forecasting (at least in the EU). I’m wondering what MS is using in Outlook. Just ISO worldwide?

Yes, I did hear it in some meetings with European colleagues before I retired. But before that, I’d never heard of the idea at all, neither at CERN, nor while working 12 years in the USA.

1 Like

In Germany it is a big thing in midsize to larger organisation. You don’t meet in 2 weeks or in 4 months, but you want to meet in “Kalenderwoche 34” or “Kalenderwoche 48” and you are on vacation in calendar week xy etc. Honestly, I think most people don’t care when the first weeks of a year starts, they trust their outlook calendar and that is showing, and that seems to be ISO (at least with the regional timezone settings for Germany).

1 Like