Get day number within calendar week for a specific date - excel

I have a data set which includes dates.
I need to split this out by week number for reporting purposes.
What I have so far is:
startDate variable containing 03/01/2015 (populated from data in spreadsheet)
startDay = Day(startDate)
startMonth = Month(startDate)
startYear = Year(startDate)
startWeek = Application.WorksheetFunction.WeekNum(DateSerial(startYear, startMonth, startDay))
which gives me week 1 in startWeek
However I know need to know how far into week 1 the date is.
So for this example, as the date is the 3rd of January, it includes 3 days of week 1
Meaning the reporting I'm putting together will only report on 3 days (as opposed to the full week)
The only way I've figured to do this so far is to calculate which day of the year the date is and the use a MOD calculation (basically divide by 7 and the remainder is how far into the week it is)
dayNumber = DateDiff("d", DateSerial(startYear, 1, 1), DateSerial(startYear, startMonth, startDay)) + 1
dayOfWeek = dayNumber Mod 7
This does work, but I was wondering if there was a nicer solution than this.

You could use a loop to determine how many days before startDate the week number changed:
Public Sub FindDaysInWeekNo()
Dim startDate As Date
startDate = DateSerial(2015, 1, 3)
Dim startWeek As Integer
startWeek = Application.WorksheetFunction.WeekNum(startDate)
Dim i As Integer
Do While startWeek = Application.WorksheetFunction.WeekNum(DateAdd("d", -i, startDate))
i = i + 1
Loop
Debug.Print i '= 3rd day in this week number
End Sub
The following table shows my comparison to the other suggested formulas and why I think that (refered to =WEEKNUM) my calculation is correct.
Note that if you assume 1st to 7th January will be week 1 (days 1 to 7) you cannot use the WeekNum function because this will give you a different result (see table above and note that the first week has only 6 days according to the WeekNum function). Also you cannot name this week number (as what everybody calls week number is defined as https://en.wikipedia.org/wiki/Week#Week_numbering).
Instead you will need to use …
Public Function AlternativeWeekNum(startDate As Date) As Integer
AlternativeWeekNum = WorksheetFunction.Days(startDate, DateSerial(Year(startDate), 1, 1)) \ 7 + 1 'note that this no normal division but a integer division and uses a backslash instead
End Function
to calculate the week number your alternative way, and …
Public Function AlternativeWeekNumDay(startDate As Date) As Integer
AlternativeWeekNumDay = WorksheetFunction.Days(startDate, DateSerial(Year(startDate), 1, 1)) Mod 7 + 1
End Function
to calculate the day in the alternative week.

You can use the Weekday() function for this:
=WEEKDAY(B4;2)
The second parameter mentions how you want your days to be counted (starting from Sunday or Monday, counting starting from 0 or from 1, ...).

dayOfWeek = (8 + Weekday(startDate) - Weekday(DateSerial(startYear, 1, 1))) mod 7
Just take the positive mod 7 of the difference between the current Day-Of-Week and the Day-Of-Week for the 1st January of whatever the year is

Related

How to get the Week of the month (1:6)

We can find different approaches to determining the week of the month, and even though there are many pages on 1:4 and/or 1:5, there is very few around 1:6 approach.
So to give you a bit of the context, I am working with a pivot table in Excel which gets its values from a Power Query source.
In Power Query, there is a function Date.WeekOfMonth which takes in the date and returns a number between 1 and 6.
In this definition, weeks start from Sunday and ends on Saturday.
So, for example, the first two days of October 2021 -i.e. Fri & Sat- fall in the 1st week of Oct, while the 3rd day of Oct 2021 starts the second week, and then the last day of October 2021,i.e. Oct 31, is the only day in the 6th week.
I had an automation task on hand in which I needed to pull data from the Power Query-generated pivot, so I had to implement a piece of code in VBA which calcs weeks the same.
Unfortunately, I couldn't find any prepared snippet, so after implementing I though it might worth sharing.
(Any comments and suggestions appreciated)
The DatePart function is perfect for this. Using DatePart with the interval set to "weeks" you can find the week of a given date. Then you subtract the number of weeks before the first day of that month (which sets the first day to week = 1).
Function WeekNumOfDate(D As Date) As Integer
WeekNumOfDate = DatePart("ww", D) - DatePart("ww", DateSerial(Year(D), Month(D), 1)) + 1
End Function
Here is a second version of the function that has the ability to set the FirstDayOfWeek argument:
Function WeekNumOfDate(D As Date, Optional FirstDayOfWeek As VbDayOfWeek = vbSunday) As Integer
WeekNumOfDate = DatePart("ww", D, FirstDayOfWeek) - DatePart("ww", DateSerial(Year(D), Month(D), 1), FirstDayOfWeek) + 1
End Function
As an example for using FirstDayOfWeek: With FirstDayOfWeek set to vbThursday, the date "Nov 5th, 2021" will return as Week 2, whereas it would by default be counted as Week 1. November 1st to 3rd of 2021 will be week 1, and then 4th to 10th will be week 2.
Its implementation in VBA is:
Function WeekOfMonth(My_Date As Date)
If Day(My_Date) > Day(My_Date - 1) And Weekday(My_Date) > Weekday(My_Date - 1) Then
WeekOfMonth = WeekOfMonth(My_Date - 1)
ElseIf Day(My_Date) > Day(My_Date - 1) And Weekday(My_Date) < Weekday(My_Date - 1) Then
WeekOfMonth = WeekOfMonth(My_Date - 1) + 1
Else
WeekOfMonth = 1
End If
End Function
Note that even though the above function is recursive, its time and space complexity is an expression of order N, which here cannot exceed 31.

vba - get weeknumber

I would like to get the current week number.
I tried this:
MsgBox (Format(Now, "ww", vbMonday))
The result:
3
But it has to be 2
Where is my mistake?
msgbox format(now(),"ww",vbMonday,vbFirstFourDays)
provides the ISO weeknumber, which is what it seems you want.
or:
msgbox worksheetfunction.IsoWeekNum(date)
Note that there is a bug in the VBA Format (and DatePart) functions in that they can return the wrong weeknumber for the last Monday of some years when determining the ISO WeekNumber
So if you are going to use the Format function, you need to check for that bug.
Worksheetfunction.IsoWeekNum does not have that bug.
To workaround the bug, Microsoft suggests checking the weeknumber of the week after any date where the weeknumber calculates to 53.
Function WOY (MyDate As Date) As Integer ' Week Of Year
WOY = Format(MyDate, "ww", vbMonday, vbFirstFourDays)
If WOY > 52 Then
If Format(MyDate + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then WOY = 1
End If
End Function

How to define a variable in between 2 date periods and time periods?

So I'm trying to define a variable or multiple variable so I can easily filter in my data set. Essentially I need to filter by date/time in my data set. The format of the date and time in the data set is as such: 2019-01-03 8:45:30 PM
What I want to do is to define a variable in order to always filter the data based on the current date. My data always changes every day, therefore my point of reference is today's date. Essentially I need to filter data starting from 2 days ago at 11am all the way to yesterdays date ending at 10am. How would i go about defining my variable? I tried doing the following:
Dim StandardH As Date
StandardH = Date - 1 + (1 / 24)
And do the same thing all the way to 10 am and do - (1/24) all the way till 11am but that doesn't seem to work.
I realize that there's probably a simpler way of doing this. Any ideas?
Thanks,
In VBA:
"2 days ago at 11 AM" translates to Date - 2 + TimeSerial(11, 0, 0)
"Yesterday at 10 AM" translates Date - 1 + TimeSerial(10, 0, 0)
That's in relation to the date and time the code is being run, and assumes by "2 days ago" you mean "the day prior to yesterday".
If I had some dates on "Sheet4" in the range "B7:B17" (assume there is a header in cell B6), then I think I could use the code below to filter from (and including) 2 days ago at 11 AM, up to (and including) yesterday at 10 AM:
Option Explicit
Sub FilterDatesInclusively()
With ThisWorkbook.Worksheets("Sheet4")
.AutoFilterMode = False
Dim fromDate As Date
fromDate = Date - 2 + TimeSerial(11, 0, 0)
Dim toDate As Date
toDate = Date - 1 + TimeSerial(10, 0, 0)
.Range("B6:B17").AutoFilter Field:=1, Criteria1:=">=" & CDbl(fromDate), Operator:=xlAnd, Criteria2:="<=" & CDbl(toDate)
End With
End Sub
Maybe there is some way of filtering without converting to double, but I couldn't work it out.

Start the Week Number from the first sunday of every fiscal year in Excel

I am trying to find the week number for a fiscal year which is starts on first sunday of February. I have got it to a point where I can get the week number which starts on first of every year (in my case feb).
Not able to start it from First Sunday. Below is what I've come up with.
=IF(AND(MONTH($E2)=2,DAY($E2)=1),1,ROUNDUP(($E2-DATE(YEAR($E2)-IF(MONTH($E2)<2,1,0),2,0)+WEEKDAY(DATE(YEAR($E2)-IF(MONTH($E2)<2,1,0),2,0)))/7,0))
I would also like it to end on Saturday of last week of the year.
For example: in Feb 2016, the week count should start from 7thFeb2016 and the count should end on 4thFeb2017.
Use this formula to find week number of given date:
=IF(A1>=IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1),2,1),DATE(YEAR(A1),2,7-WEEKDAY(DATE(YEAR(A1),2,1),1)+2)),ROUNDUP((A1-IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1),2,1),DATE(YEAR(A1),2,7-WEEKDAY(DATE(YEAR(A1),2,1),1)+2))+1)/7,0),ROUNDUP((A1-IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1)-1,2,1),DATE(YEAR(A1)-1,2,7-WEEKDAY(DATE(YEAR(A1)-1,2,1),1)+2))+1)/7,0))
I hope you want this.
UPDATED
If you want week number of fiscal quarter, use this:
=ROUNDUP(MOD(=IF(A1>=IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1),2,1),DATE(YEAR(A1),2,7-WEEKDAY(DATE(YEAR(A1),2,1),1)+2)),ROUNDUP((A1-IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1),2,1),DATE(YEAR(A1),2,7-WEEKDAY(DATE(YEAR(A1),2,1),1)+2))+1)/7,0),ROUNDUP((A1-IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1)-1,2,1),DATE(YEAR(A1)-1,2,7-WEEKDAY(DATE(YEAR(A1)-1,2,1),1)+2))+1)/7,0)),13.01),0)
I just chucked this together (no doubt there is a more elegant way to do this). You can use it by putting it into a Module in your VBA editor and then on the worksheet use the function =AltWeekNumber(E2)
Function AltWeekNumber(endDate As Range) As Date
Dim startDate As Date
startDate = FirstFebruarySunday(year(endDate.Value))
If startDate > endDate Then
startDate = FirstFebruarySunday(year(endDate.Value) - 1)
End If
AltWeekNumber = DateDiff("w", startDate, endDate.Value, vbSunday)
End Function
Private Function FirstFebruarySunday(year As Integer) As Date
For i = 1 To 7
If Weekday(DateSerial(year, 2, i)) = 1 Then
FirstFebruarySunday = DateSerial(year, 2, i)
Exit Function
End If
Next i
End Function

Week number to Month number

I have a date with this format : 14w01 (year : 2014 week number : 1)
I want to convert this date in month like this : 14m01
Is there a function which converts a week number in a month number ?
Maybe something like this (in vba, not in formula) :
Format(weekNumber, "mm")
Thank you
It depends on how the weeks are defined. One way is to say that the first day of week#1 of a year is 1 January of that year. For this definition, a typical UDF is:
Public Function MonthFromDt(s As String) As Integer
Dim yr As Integer, wk As Integer, d As Date
ary = Split(s, "w")
yr = CInt(ary(0)) + 2000
wk = ary(1)
MonthFromDt = Month(DateSerial(yr, 1, 1) + 7 * (wk - 1))
End Function
There are other definitions of week number.
The DateFormat function is quiet comfortable, however the DateValue function, which parses a date, won't probably support your week format.
I suggest a trick with DateAdd, as DateAdd can handle weeks.
First split your date in year and week number:
Dim parts
parts = Split("2014w33", "w")
Dim year
Dim week
year = CInt(parts(0))
week = CInt(parts(1))
Then, add both to a "zero-date" to add up to the final date. Note that if you give "0" as year for DateAdd, VBA compiler interprets 2000.
dim DateResult
DateResult = dateAdd("yyyy", (year - 2000), DateValue("Jan 1, 0"))
Debug.Print dateResult
DateResult = dateAdd("ww", week, dateResult)
Debug.Print dateResult
Then show the result reformatted:
Debug.Print Format(DateResult, "yyyy\mm")
This prints on my side:
01.01.2014
20.08.2014
2014m08
August 2014, there is week 33 if I look up in the calendar. Seems correct.
I found a way to do it without VBA (and only using Formulas). This assumes A1 contains the "14w01" format
=LEFT(A1,2)&"m"&TEXT(MONTH(DATE(20&LEFT(A1,2),1,1)+(RIGHT(A1,2)*7)),"00")
Heres a breakdown of what the code does..
LEFT(A1,2) returns "14" (year)
MONTH(DATE(20&LEFT(A1,2),1,1)+(RIGHT(A1,2)*7)) converts the week # to the month # and it takes in the year 20&LEFT(A1,2) as well as week # RIGHT(A1,2)
TEXT(...,"00") pads the month # with a 0 if necessary (i.e. 3 becomes 03)
Then we just combine everything together to get "14m01"

Resources