Main Contents

Calculating ISO8601 week numbers in LotusScript

June 1, 2010

Lotus Domino’s LotusScript language has a function called Format. If you pass it a date/time value, and use the custom format string "ww", it’s supposed to return the week number.

Unfortunately, it returns the wrong value. I was prepared to be charitable and assume that it returned the correct value according to some non-standard algorithm, but since the documentation didn’t specify the algorithm, I reported the behavior as a bug. My SPR got filed in the “Yes, it’s a bug, but we won’t fix it” pile, so here’s the workaround: LotusScript code to calculate week numbers as per ISO 8601. (Also available on GitHub)

Function WeekNumber(t As NotesDateTime) As String
' Wrapper to work out week numbers of NotesDateTime objects in the current time zone
Dim lst As Variant
lst = t.LSLocalTime
WeekNumber = LSWeekNumber(lst)
End Function

Function LSWeekNumber(t As Variant) As String
' Returns the week number of a NotesDateTime object
' computed in the local time zone according to ISO 8601
' which states that week 1 is the week containing the first Thursday
' (or, equivalently, the week containing January 4th).
' Returns a 7-character string; example: "2010W05"
' First, strip any time information and get year, month, day, and day-of-week
  Dim lst As Variant
  lst = Int(t)
  Dim yyyy As Integer
  yyyy = Year(lst)
  Dim mm As Integer
  mm = Month(lst)
  Dim dd As Integer
  dd = Day(lst)
  dow = Weekday(lst)
' The first special cases are when the first week of the next year protrudes back into this year
' and we've been asked to compute week number for a date right at the end of the year
  If (mm = 12) Then
    If (dd >=29 And dow = 2) Or (dd >= 30 And dow = 3) Or (dd = 31 And dow = 4) Then
      LSWeekNumber = Trim(Str(yyyy)) & "W" & "01"
      Exit Function
    End If
  End If
' OK, not a special case, so we have some work to do
' Create a date number for the first day of the year
  Dim fdoy As Variant
  fdoy = Datenumber(yyyy, 1, 1)
' Work out what day of the week that was
' Note that Notes uses Sunday = 1, which is non-standard as per ISO 8601
  Dim fdow As Integer
  fdow = Weekday(fdoy)
' Compute offset
  Dim offset As Integer
  If (fdow > 5) Then
    offset = fdow - 9
  Else
    offset = fdow - 2
  End If
' Compute week number
  Dim wn As String
  wn = Right("0"&Trim(Str(Int(((lst + offset) - fdoy) / 7) + 1)), 2)
  If (wn = "00") Then
' It's the last week number of the previous year,
' i.e. the week number it was on December 31st of that year
' so call ourselves recursively to compute that
    wn = Right(LSWeekNumber(Datenumber(yyyy-1, 12, 31)), 2)
    LSWeekNumber = Trim(Str(yyyy - 1)) & "W" & wn
    Exit Function
  End If
  LSWeekNumber = Trim(Str(yyyy)) & "W" & wn
End Function

Filed under: LotusScript, Programming | Comments (0)

Leave a comment

Login