Get Date from Week number and Day of the week (1 Viewer)

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
I am trying to work our which function to use to obtain the date (dd/mm/yyyy) of a specific day of the week for a particular week number in a query.

I know the week number and the specific day of the week but I need to find the DATE from these two pieces of information.

This example shows what I am trying to achieve but I have populated the date I need to get from the function.

WeekID Day Date
22 Mon 29-05-17
22 Tue 30-05-17
22 Wed 31-05-17
22 Thu 01-06-17
22 Fri 02-06-17
23 Mon 05-06-17
23 Tue 06-06-17
23 Wed 07-06-17
23 Thu 08-06-17
23 Fri 09-06-17

Ive got myself tied up in knots trying to use DatePart, DateAdd, DateSerial but not really knowing what I am doing. Please can someone help?
 

Ranman256

Well-known member
Local time
Today, 01:24
Joined
Apr 9, 2015
Messages
4,339
in a query,
format([date],"ddd") , returns MON ,for day of week
format([date],"ww") , returns 35 , for week in the year
 

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
in a query,
format([date],"ddd") , returns MON ,for day of week
format([date],"ww") , returns 35 , for week in the year

thanks but this is not what I need. Maybe I didnt explain clearly enough.

I already have the week number and the day. I need to work out the Date based upon the week and the day of the week.
Its the date i need to calculate.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 00:24
Joined
Feb 28, 2001
Messages
27,148
You need one more item to finish this process.

First, you know the week number because that is one of your inputs. Second, you know the day of the week within that week because that is one of your inputs. But THIRD, you need to know the basis of computing the week number.

You see, when you compute a week number, you base that on a starting day of the week for the year. That is because some people want to start the week on the first day of the year even if that day isn't Sunday (or Monday or whatever). So the computation routines that manipulate these dates take into account the starting day of the week.

See these articles:

https://www.techonthenet.com/access/functions/date/format.php

https://msdn.microsoft.com/en-us/library/aa262714(v=vs.60).aspx

Both the FORMAT function and the DATEPART function include the optional starting information for your virtual calendar. Read the articles I referenced if you weren't familiar with these functions.

Format ( expression, [ format, [ firstdayofweek, [firstweekofyear] ] ] )

DatePart(interval, date[,firstdayofweek[, firstweekofyear]])

You also need to know if a value was used for the first week of the year. Again, look at the articles to understand your options.

Now, here is how you compute the date of the targeted weekday for that week of the year.

1. Determine the basis date for starting the week computation. I.e. when you computed the week number, what did you use for that computation? Determine the day of the year for that day of the week. You must realize from looking at the options for the FORMAT or DATEPART functions that the first week of the year MIGHT not even be in the same year if, for example, the starting day is chosen as Sunday and the starting week is chosen as the one that CONTAINS 1 Jan which happens to be a Monday. In that hypothetical case, the first week of the year starts on the Sunday that ended the previous year.

2. Compute a base-week date as DATEADD( "ww", nn-1, basis-date ) - and you need the -1 because if I recall correctly, the week number will be one-based but DATEADD won't be. That is, there is no week 0. The week that contains the selected basis-date for the year is week 1.

3. Now, the tricky part. You know the weekday for the basis date (because it is either Sunday, the default, and day = 1, or you found another value if the default was not used). You already know the day of the week for the desired day, you just don't know the date yet. Those two days will be expressed as numbers from 1 to 7.

Subtract 1 from EACH weekday number (to change them from Sunday = 1 to Sunday = 0; but more technically, to again make the numbers ZERO based, not ONE based.) Subtract the adjusted starting weekday number from the adjusted target weekday number. This is now the difference in days between the two weekdays.

If the result is zero, the weekday computation took you to the right date already. The computed week-base is the date you wanted. You are done.

If the difference is less than zero, add 7. Then (if the difference wasn't zero) compute another DATEADD( "d", difference, weekday-base ).

Let's say your day in question was a Monday but this year your week-count began on a Friday. Friday = day 6. Monday = day 2. So adjusted, equals 5 and 1. Subtract in the order stated and you get -4, which is less than 7, so add 7 and you get 3. So from your weekday base from step 2 earlier, add 3 more days and you get the date of the desired Monday.
 

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
You need one more item to finish this process.

First, you know the week number because that is one of your inputs. Second, you know the day of the week within that week because that is one of your inputs. But THIRD, you need to know the basis of computing the week number.

You see, when you compute a week number, you base that on a starting day of the week for the year. That is because some people want to start the week on the first day of the year even if that day isn't Sunday (or Monday or whatever). So the computation routines that manipulate these dates take into account the starting day of the week.

See these articles:

https://www.techonthenet.com/access/functions/date/format.php

https://msdn.microsoft.com/en-us/library/aa262714(v=vs.60).aspx

Both the FORMAT function and the DATEPART function include the optional starting information for your virtual calendar. Read the articles I referenced if you weren't familiar with these functions.

Format ( expression, [ format, [ firstdayofweek, [firstweekofyear] ] ] )

DatePart(interval, date[,firstdayofweek[, firstweekofyear]])

You also need to know if a value was used for the first week of the year. Again, look at the articles to understand your options.

Now, here is how you compute the date of the targeted weekday for that week of the year.

1. Determine the basis date for starting the week computation. I.e. when you computed the week number, what did you use for that computation? Determine the day of the year for that day of the week. You must realize from looking at the options for the FORMAT or DATEPART functions that the first week of the year MIGHT not even be in the same year if, for example, the starting day is chosen as Sunday and the starting week is chosen as the one that CONTAINS 1 Jan which happens to be a Monday. In that hypothetical case, the first week of the year starts on the Sunday that ended the previous year.

2. Compute a base-week date as DATEADD( "ww", nn-1, basis-date ) - and you need the -1 because if I recall correctly, the week number will be one-based but DATEADD won't be. That is, there is no week 0. The week that contains the selected basis-date for the year is week 1.

3. Now, the tricky part. You know the weekday for the basis date (because it is either Sunday, the default, and day = 1, or you found another value if the default was not used). You already know the day of the week for the desired day, you just don't know the date yet. Those two days will be expressed as numbers from 1 to 7.

Subtract 1 from EACH weekday number (to change them from Sunday = 1 to Sunday = 0; but more technically, to again make the numbers ZERO based, not ONE based.) Subtract the adjusted starting weekday number from the adjusted target weekday number. This is now the difference in days between the two weekdays.

If the result is zero, the weekday computation took you to the right date already. The computed week-base is the date you wanted. You are done.

If the difference is less than zero, add 7. Then (if the difference wasn't zero) compute another DATEADD( "d", difference, weekday-base ).

Let's say your day in question was a Monday but this year your week-count began on a Friday. Friday = day 6. Monday = day 2. So adjusted, equals 5 and 1. Subtract in the order stated and you get -4, which is less than 7, so add 7 and you get 3. So from your weekday base from step 2 earlier, add 3 more days and you get the date of the desired Monday.

WOW this is going to take me some time to digest and work it out but thanks.
My week number is based upon the current week and then I just keep adding 1 for the next 6 weeks. So I think if I know the start date of this week then perhaps I can calculate the dates from there. Hopefully I will be able to work it out tomorrow :)
 

plog

Banishment Pending
Local time
Today, 00:24
Joined
May 11, 2011
Messages
11,638
Your data assumes you are always calculating the date in the current year. If that's true, I think the method involved is a lot simpler. You simply have to add the difference in your required week and the current week to the current date. Then add the difference in the required day to the current day to that.

If you didn't store the days as text and instead numbers (Sun=1, Mon=2, etc.), this could have been done in 2 lines of code. Here's the code that works for your sample data:

Code:
Function get_Date(in_Week, in_Day) As Date
' determines date based on week number (in_Week) and day of week (in_Day) it is passed

ret = DateAdd("ww", in_Week - DatePart("ww", Date), Date)
' sets return value to this day of the week in whatever week requested

int_Day = 1
    ' will hold numeric value that in_Day is (e.g. Sun=1, Mon=2, etc.)
    
Select Case in_Day
    ' converts in_Day to number
    Case "Sun"
        int_Day = 1
    Case "Mon"
        int_Day = 2
    Case "Tue"
        int_Day = 3
    Case "Wed"
        int_Day = 4
    Case "Thu"
        int_Day = 5
    Case "Fri"
        int_Day = 6
    Case "Sat"
        int_Day = 7
End Select


ret = DateAdd("d", int_Day - Weekday(Date), ret)
' moves return value based on how many days after requested day it is now

get_Date = ret
End Function

Paste that into a module, then in a query you use it like so:

DateOfData: get_Date([WeekId], [Day])
 

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
Your data assumes you are always calculating the date in the current year. If that's true, I think the method involved is a lot simpler. You simply have to add the difference in your required week and the current week to the current date. Then add the difference in the required day to the current day to that.

If you didn't store the days as text and instead numbers (Sun=1, Mon=2, etc.), this could have been done in 2 lines of code. Here's the code that works for your sample data:

Code:
Function get_Date(in_Week, in_Day) As Date
' determines date based on week number (in_Week) and day of week (in_Day) it is passed

ret = DateAdd("ww", in_Week - DatePart("ww", Date), Date)
' sets return value to this day of the week in whatever week requested

int_Day = 1
    ' will hold numeric value that in_Day is (e.g. Sun=1, Mon=2, etc.)
    
Select Case in_Day
    ' converts in_Day to number
    Case "Sun"
        int_Day = 1
    Case "Mon"
        int_Day = 2
    Case "Tue"
        int_Day = 3
    Case "Wed"
        int_Day = 4
    Case "Thu"
        int_Day = 5
    Case "Fri"
        int_Day = 6
    Case "Sat"
        int_Day = 7
End Select


ret = DateAdd("d", int_Day - Weekday(Date), ret)
' moves return value based on how many days after requested day it is now

get_Date = ret
End Function

Paste that into a module, then in a query you use it like so:

DateOfData: get_Date([WeekId], [Day])

WOW you are a genius, thank you so much. I could store the day as a number, and in fact I would much prefer to do that, so would you be able to provide me with the cut down version of the two lines of code please? It might teach me a thing or two.

Thank you for helping a damsel in distress ;)
 

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
Think I have worked it out that I just need these lines of code

Code:
Function get_Date(in_Week, in_Day) As Date
' determines date based on week number (in_Week) and day of week (in_Day) it is passed

ret = DateAdd("ww", in_Week - DatePart("ww", Date), Date)
' sets return value to this day of the week in whatever week requested

ret = DateAdd("d", int_Day - Weekday(Date), ret)
' moves return value based on how many days after requested day it is now

get_Date = ret
End Function

Once again, many thanks.
 

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
Apologies but I have just noticed that when I use the numerical value for the day number that the dates returned are incorrect for me because the start of the week for me is Monday so Mon = 1. What do I need to change in order to specify the start of the week.

I have tried playing around before asking but I just cant get it.
 

plog

Banishment Pending
Local time
Today, 00:24
Joined
May 11, 2011
Messages
11,638
Is Monday really the first day of your week? Your example data did not include any Saturday or Sunday data. That makes me believe that you do not expect those dates in your data. If so, then the value for Sunday is irrelevant and I suggest you make Monday=2.
 

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
Is Monday really the first day of your week? Your example data did not include any Saturday or Sunday data. That makes me believe that you do not expect those dates in your data. If so, then the value for Sunday is irrelevant and I suggest you make Monday=2.

Yes Monday is my first day of the week. There wont be any data with Saturday or Sunday dates. But I can adjust the numbers accordingly anyway so that Mon = 2 and so on. Thanks again.

For another exercise I am now trying to get a date from the second week of a given month and day. For example I have a table with Day and MonthNum and need to find the date for the second week of that particular month but for the specified day.

Day = Tue
MonthNum = 5
dd/mm/yyyy ? (I need to return the date that is in the second week for the specified day)
So the example above for this year would be 09/05/2017

Shall I create a new thread for this, hope you are able to help me again.
Thanks
 

plog

Banishment Pending
Local time
Today, 00:24
Joined
May 11, 2011
Messages
11,638
It would be a similar approach to the previous code I posted, however your starting date would be the first of the month. You would start out by using DateValue (https://www.techonthenet.com/access/functions/date/datevalue.php) to set your initial date. You would then add one week to it using DateAdd, and finally use the day method of my original code to accomodate what day of the week you neeeded.
 

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
It would be a similar approach to the previous code I posted, however your starting date would be the first of the month. You would start out by using DateValue (https://www.techonthenet.com/access/functions/date/datevalue.php) to set your initial date. You would then add one week to it using DateAdd, and finally use the day method of my original code to accomodate what day of the week you neeeded.

The trouble is I don't have a starting date so dont think I can use DateValue. My starting point is a Month number and I want to be able to create a date for first Monday in that month and then calculate all the dates I need in the second week of that month (but specify the day) but I just dont know how to do this.

I have a table with month number from 1 to 24 (so that I have a rolling year) but i want my system to dynamically update the dates each time the process is ran.
 

plog

Banishment Pending
Local time
Today, 00:24
Joined
May 11, 2011
Messages
11,638
Yes, you do have a starting point, the first of the month. Reread my post, it details the method.
 

Snowflake68

Registered User.
Local time
Today, 06:24
Joined
May 28, 2014
Messages
452
Yes, you do have a starting point, the first of the month. Reread my post, it details the method.[/QUOTE

I don't have the first of the month as I would need to dynamically create it depending on what year I am in. So how do I generate the first of the month using only the month number?
 

plog

Banishment Pending
Local time
Today, 00:24
Joined
May 11, 2011
Messages
11,638
You would use the DateValue function
 

Users who are viewing this thread

Top Bottom