Home > Enterprise >  Convert week number and year to a date in Access-SQL?
Convert week number and year to a date in Access-SQL?

Time:02-17

In Microsoft Access, I have a table where number of hours worked per weekday are associated to a project number, ISO-week number and year. Simplified, it looks like this:

ProjectID WeekNumber YearNumber Monday Tuesday
1 1 2022 5 6
1 2 2022 7 8

I am trying to set up a query where all weekday columns (monday to sunday) are "merged" into one column and the week and year numbers are converted to dates. It should look like this:

ProjectID Date HoursPerDay
1 03.01.2022 5
1 04.01.2022 6
1 10.01.2022 7
1 11.01.2022 8

I managed to merge all weekday columns into one column using a UNION query:

SELECT ProjectID, WeekNumber, YearNumber, Monday As HoursPerDay FROM ProjectHours
UNION ALL
SELECT ProjectID, WeekNumber, YearNumber, Tuesday As HoursPerDay FROM ProjectHours;

The result looks like this:

ProjectID WeekNumber YearNumber HoursPerDay
1 1 2022 5
1 1 2022 6
1 2 2022 7
1 2 2022 8

But I am stuck converting the iso-week and year number to a date. Is this at all possible in Access-SQL?

I found this question on Stackoverflow and went through the date/time functions that Microsoft lists for Access but could not get it to work.

Any help is highly appreciated.

EDIT: A community member has suggested a possible duplicate of this question, but I am looking for a solution that I can use in an Access-SQL query, so the suggested duplicate does not help me, as it suggests a VBA based solution.

CodePudding user response:

This is not so simple, as the ISO years rarely are in sync with calendar years.

But this function will do:

' Returns the date of Monday for the ISO 8601 week of IsoYear and Week.
' Optionally, returns the date of any other weekday of that week.
'
' 2017-05-03. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function DateYearWeek( _
    ByVal IsoWeek As Integer, _
    Optional ByVal IsoYear As Integer, _
    Optional ByVal DayOfWeek As VbDayOfWeek = VbDayOfWeek.vbMonday) _
    As Date
    
    Dim WeekDate    As Date
    Dim ResultDate  As Date
    
    If IsoYear = 0 Then
        IsoYear = Year(Date)
    End If
    
    ' Validate parameters.
    If Not IsWeekday(DayOfWeek) Then
        ' Don't accept invalid values for DayOfWeek.
        Err.Raise DtError.dtInvalidProcedureCallOrArgument
        Exit Function
    End If
    If Not IsWeek(IsoWeek, IsoYear) Then
        ' A valid week number must be passed.
        Err.Raise DtError.dtInvalidProcedureCallOrArgument
        Exit Function
    End If
    
    WeekDate = DateAdd(IntervalSetting(dtWeek), IsoWeek - 1, DateFirstWeekYear(IsoYear))
    ResultDate = DateThisWeekPrimo(WeekDate, DayOfWeek)
    
    DateYearWeek = ResultDate

End Function

However, it uses a series of supporting functions, like:

' Returns the primo date of the week of the date passed.
'
' 2016-01-13. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function DateThisWeekPrimo( _
    ByVal DateThisWeek As Date, _
    Optional ByVal FirstDayOfWeek As VbDayOfWeek = vbSunday) _
    As Date

    Dim Interval    As String
    Dim Number      As Double
    Dim ResultDate  As Date
    
    Number = 0
    Interval = IntervalSetting(DtInterval.dtWeek)
    
    ResultDate = DateIntervalPrimo(Interval, Number, DateThisWeek, FirstDayOfWeek)
    
    DateThisWeekPrimo = ResultDate
    
End Function

and several more - way too much to post here.

So, please refer to my project at GitHub, VBA.Date, for the modules holding the full code.

  • Related