Tag: Date table
-

Power BI Date Dimension Demystified Part 2
Hello All, let us continue with our journey of demystifying the Date Dimension.
In my last post, we learned to use CALENDARAUTO() function. We will continue today with the second DAX function called Calendar(). We will also look at how to extract other “relevant columns” such as year, month name, month number, etc. I will go over the following in this post.
- Create a date column using the CALENDAR() function.
- Use multiple DAX formulas to extract/add these columns.
- Use one DAX formula to generate the entire Date Table that will include all these columns.
- Dynamic dates selection and usage.
CALENDAR() Function:
The CALENDAR() functions take two parameters, StartDate, End Date, and return a table with one column with all dates between the StartDate and EndDate.
For this exercise, let StartDate be 01/01/2020 and EndDate be 12/31/2020.
If you follow this series from Part 1, then your environment is already set, and follow along. If you are new and want to follow the same dataset, please go through Part 1 and the Power Query.
Let us begin by navigating to the Modeling tab, click on the New Table, and use the following code to create a column in this table containing all the dates between the start and end date as shown below.
date table using calendar = CALENDAR(DATE(2020,01,01), DATE(2020,12,31))


Once you hit enter, you should have the Date Column in your model. To view it, click on the data tab on the left, and you should be a single column in this table of Date/Time datatype ranging from 1/1/2020 to 12/31/2020 as shown below.

As you can see we have a very similar result to what we had in Part 1. Since in Part 1 we used CALENDARAUTO(), Power BI fetched the minimum (start-date) and maximum (end-date) automatically from our model. However, for the CALENDAR() function, we need to specify the StartDate and EndDate.

Once we have this column, we can then extract important and relevant information regarding the date. We will be extracting information such as Month Number, Year, Month Name, Weekday, Quarter, Second approach to Quarter, Week Number, Day Number of the Month, WeekDay Number of the week.
I have included all these code snippets as follows to follow along with me as I do this. After the Date Column is created (using the approach above), all we need to do is create a new column for each of the relevant details.
To create the Month Number:
- Click on the Data tab on the left on the Power BI Desktop.
- Once you are in the Data tab, you should see the date table we created above on the right under the field.
- If you followed along, then you should have a table named “date table using the calendar.”
- Click on the new column icon.
- Enter the following formula in the formula bar.
- Month Number = Month(‘date table using calendar'[Date])
- Press enter.
- Your new column named Month Number is ready.
- Follow the same process for Month Name, Year, Weekday, Quarter, Quarter Second Approach, Week Number, Day Number, Weekday Number.

Use the following code snippets to generate these columns. I have included the images of the next two columns as an example.


We have already done the first and second below.
- date table using calendar = CALENDAR(DATE(2020,01,01), DATE(2020,12,31))
- Month Number = MONTH(‘date table using calendar'[Date])
- Month Name = FORMAT(‘date table using calendar'[Date], “mmmm”)
- Year = YEAR(‘date table using calendar'[Date])
- Weekday = FORMAT(‘date table using calendar'[Date], “dddd”)
- Quarter = Var monthnum = MONTH(‘date table using calendar'[Date])
Return
SWITCH
(
TRUE(),
monthnum <=3, “Q1”,
monthnum > 3 && monthnum <= 6, “Q2”,
monthnum > 6 && monthnum <= 9, “Q3”,
monthnum > 9, “Q4”
)
- Quarter Second Approach =
// storing the month number in a variable called mnth
var mnth = MONTH(‘date table using calendar'[Date])
// getting the quarters
var myqrt = ((mnth -1)/3 ) + 1
// truncate this result using Trunc function and WITHOUT passing the optional params
var trnc = TRUNC(myqrt)
// concat the alpahbet Q to this result
var addQ = “Q ” & trnc
// Retun this
return addQ
- Weeknumber = WEEKNUM(‘date table using calendar'[Date])
- Day Number of the month = DAY(‘date table using calendar'[Date])
- Weekday number of the week = WEEKDAY(‘date table using calendar'[Date])
You should have the following columns in your date table by now.

Let us take a pause here and create these columns using the Part 1 approach. In that post, we used Calendarauto() function. Using the same approach let us create other columns.
- Once again navigate to the Data tab.
- Click the table named date table from calendarauto.
- Click on the new column and enter the code snippets
These are the code snippets for the CALENDARAUTO() function. Please note that the start date and end date will be different for both these functions. The reason being in CALENDAR() we are specifying the StartDate and EndDate, whereas in CALENDATAUTO() it identifies the start date and end date based on the model. We have covered the CALENDARAUTO() in detail in the previous post here.
// all the columns for the Date Table from the start
- date table from calendarauto DAX = CALENDARAUTO()
- Month Number = MONTH(‘date table from calendarauto DAX'[Date])
- Month Name = FORMAT(‘date table from calendarauto DAX'[Date], “mmmm”)
- Year = YEAR(‘date table from calendarauto DAX'[Date])
- Weekday = FORMAT(‘date table from calendarauto DAX'[Date], “dddd”)
- Quarter = Var monthnum = MONTH(‘date table from calendarauto DAX'[Date])
Return
SWITCH
(
TRUE(),
monthnum <=3, “Q1”,
monthnum > 3 && monthnum <= 6, “Q2”,
monthnum > 6 && monthnum <= 9, “Q3”,
monthnum > 9, “Q4”
)
- Quarter Second Approach =
// storing the month number in a variable called mnth
var mnth = MONTH(‘date table from calendarauto DAX'[Date])
// getting the quarters
var myqrt = ((mnth -1)/3 ) + 1
// truncate this result using Trunc function and WITHOUT passing the optional params
var trnc = TRUNC(myqrt)
// concat the alpahbet Q to this result
var addQ = “Q ” & trnc
// Retun this
return addQ
- Weeknumber = WEEKNUM(‘date table from calendarauto DAX'[Date])
- Day Number of the month = DAY(‘date table from calendarauto DAX'[Date])
- Weekday number of the week = WEEKDAY(‘date table from calendarauto DAX'[Date])

Awesome !!! we now have a date table with relevant data using both Calendar and Calendarauto approach. Let us dig a little deep into these DAX formulas that we have written. If you notice, we created multiple calculated columns based on the very first date column. This is okay to do so. However, we can combine all these separate DAX formulas into one.
For this let us create an entire date table using a single DAX formula and adding these columns within it.
- Click on the modeling tab.
- Click on the new table icon.
- Paste the following code snippet.
- Once you press enter, your entire date table will be ready and populated.
Date Using DaxCal Calendar =
// This variable is storing the column values
VAR DaxCal =
CALENDAR ( DATE ( 2020, 01, 01 ), DATE ( 2020, 12, 31 ) )
RETURN
// AddColumns returns a table with new columns specified by the DAX expressions
ADDCOLUMNS (
DaxCal,
“Year”, YEAR ( [Date] ),
“Month Number”, MONTH ( [Date] ),
“Month Name”, FORMAT ( [Date], “mmmm” ),
“Quarter”,
“Q “
& TRUNC ( ( ( MONTH ( [Date] ) – 1 ) / 3 ) + 1 ),
“WeekNum”, WEEKNUM ( [Date] ),
“Day of the Month”, DAY ( [Date] ),
“Weekday Number of the Week”, WEEKDAY ( [Date] ),
“Weekday Name”, FORMAT ( [Date], “dddd” ),
“Full Date Only”, FORMAT ( [Date], “mm/dd/yyyy” )
)
You should have a date table as shown below.

Let us break down the code.
- We are calling Calendar Function just like we did before. However this time we are storing the result in a Variable.
- We then want to return a table with other columns created using the DAX expressions.
- To do so we are calling the ADDCOLUMNS function.
- The first parameter we need to pass is the name of the table. In this case, it is our variable. I called it DaxCal.
- The next parameter is the name of the column. I called it Year.
- The last parameter is the DAX expression. In this case, it is YEAR([DATE]).
- Follow the same process till all the other columns have been called.
I have included the very similar code snippet for CALENDATAUTO() function that was used in Part 1.
Date Using DaxCal Calendarauto =
VAR DaxCal =
CALENDARAUTO ()
RETURN
ADDCOLUMNS (
DaxCal,
“Year”, YEAR ( [Date] ),
“Month Number”, MONTH ( [Date] ),
“Month Name”, FORMAT ( [Date], “mmmm” ),
“Quarter”,
“Q “
& TRUNC ( ( ( MONTH ( [Date] ) – 1 ) / 3 ) + 1 ),
“WeekNum”, WEEKNUM ( [Date] ),
“Day of the Month”, DAY ( [Date] ),
“Weekday Number of the Week”, WEEKDAY ( [Date] ),
“Weekday Name”, FORMAT ( [Date], “dddd” ),
“Full Date Only”, FORMAT ( [Date], “mm/dd/yyyy” )
)

Though we have created a Date Table, we are not done yet. Let us improve on this approach. What we just did is what I call the brute force method of creating a Data Table using the Calendar function. What I mean by this is that we hardcoded the StartDate and EndDate values in this.
Let us take this further and make it dynamic. If you remember from my previous post, There are 3 Main Things we need. StartDate, EndDate, and Duration. Once again I will reiterate that please remember this as this will help us understand the concept of Date Table when we create the Date Dimension using M Query in the future posts.
By now we know that the function CALENDAR() requires StartDate and EndDate. For now, we handed it by providing static values. Let us make it more dynamic.
Let us say, that we needed our date table to start from the first Order date as the StartDate and the last ship date as the EndDate.
To do so we will declare two more variables as follows.
Date Using DaxCal Calendar Dynamic =
// we are getting the minimum of the Order Date and storing it in a variable
Var MinDate = MIN(OrdersData[Order Date])// we are getting the latest Ship Date and storing it in a variable
Var MaxDate = MAX(OrdersData[Ship Date])// Calling the Calendar function and passing into it, the two variables as the arguments and returning the result with relevant columns
VAR DaxCal =
CALENDAR(MinDate,MaxDate)
RETURN
ADDCOLUMNS (
DaxCal,
“Year”, YEAR ( [Date] ),
“Month Number”, MONTH ( [Date] ),
“Month Name”, FORMAT ( [Date], “mmmm” ),
“Quarter”,
“Q “
& TRUNC ( ( ( MONTH ( [Date] ) – 1 ) / 3 ) + 1 ),
“WeekNum”, WEEKNUM ( [Date] ),
“Day of the Month”, DAY ( [Date] ),
“Weekday Number of the Week”, WEEKDAY ( [Date] ),
“Weekday Name”, FORMAT ( [Date], “dddd” ),
“Full Date Only”, FORMAT ( [Date], “mm/dd/yyyy” )
)
With this we were able to use two DAX functions, CALENDAR() and CALENDARAUTO(), to create the date table with additional columns as needed. I hope that I was able to shed some light on these two DAX functions. In the file below you will find all the code snippets that we used thus far.
All the columns for the Date Table using CALENDAR()
// all the columns for the Date Table from the start -- CALENDAR() date table using calendar = CALENDAR(DATE(2020,01,01), DATE(2020,12,31)) Month Number = MONTH('date table using calendar'[Date]) Month Name = FORMAT('date table using calendar'[Date], "mmmm") Year = YEAR('date table using calendar'[Date]) Weekday = FORMAT('date table using calendar'[Date], "dddd") Quarter = Var monthnum = MONTH('date table using calendar'[Date]) Return SWITCH ( TRUE(), monthnum <=3, "Q1", monthnum > 3 && monthnum <= 6, "Q2", monthnum > 6 && monthnum <= 9, "Q3", monthnum > 9, "Q4" ) Quarter Second Approach = // storing the month number in a variable called mnth var mnth = MONTH('date table using calendar'[Date]) // getting the quarters var myqrt = ((mnth -1)/3 ) + 1 // truncate this result using Trunc function and WITHOUT passing the optional params var trnc = TRUNC(myqrt) // concat the alpahbet Q to this result var addQ = "Q " & trnc // Retun this return addQ Weeknumber = WEEKNUM('date table using calendar'[Date]) Day Number of the month = DAY('date table using calendar'[Date]) Weekday number of the week = WEEKDAY('date table using calendar'[Date])All the columns for the Date Table using CALENDARAUTO()
// all the columns for the Date Table from the start -- CALENDARAUTO() date table from calendarauto DAX = CALENDARAUTO() Month Number = MONTH('date table from calendarauto DAX'[Date]) Month Name = FORMAT('date table from calendarauto DAX'[Date], "mmmm") Year = YEAR('date table from calendarauto DAX'[Date]) Weekday = FORMAT('date table from calendarauto DAX'[Date], "dddd") Quarter = Var monthnum = MONTH('date table from calendarauto DAX'[Date]) Return SWITCH ( TRUE(), monthnum <=3, "Q1", monthnum > 3 && monthnum <= 6, "Q2", monthnum > 6 && monthnum <= 9, "Q3", monthnum > 9, "Q4" ) Quarter Second Approach = // storing the month number in a variable called mnth var mnth = MONTH('date table from calendarauto DAX'[Date] ) // getting the quarters var myqrt = ((mnth -1)/3 ) + 1 // truncate this result using Trunc function and WITHOUT passing the optional params var trnc = TRUNC(myqrt) // concat the alpahbet Q to this result var addQ = "Q " & trnc // Retun this return addQ Weeknumber = WEEKNUM('date table from calendarauto DAX'[Date]) Day Number of the month = DAY('date table from calendarauto DAX'[Date]) Weekday number of the week = WEEKDAY('date table from calendarauto DAX'[Date])In the next blog post, we will create Date Dimension using Power Query. If you have questions/queries/comments please do not hesitate to reach out to me.
Till next time !!!!
-

Power BI Date Dimension Demystified Part 1
Hello All, today, let us take the first step towards demystifying the Date Table journey. Date Dimension plays a vital role.
Almost always, there is a need to perform and derive time-based insights. Few ground rules must be adhered to when it comes to creating a robust date table. These are :
- The date table must contain unique values
- The date table must contain no null values
- The date table must contain contiguous date values (from beginning to end)
This series of articles will go over different manipulations/iterations of how one can achieve this.
For any date table, we must have 3 values/properties present: the start date, the end date, and the duration. For these articles, let us call them 3P, as we will be revisiting them.
The start date — This the first (earliest) date available. We can either enter this manually (using the calendar() function — coming up in the next article) or calculated it based on the model.
The end date — This is the last (latest) date available. We can either enter this manually (using the calendar() function — coming up in the next article) or calculated it based on the model.
The duration — This is the increment or step. Almost always, this increment is “day.” For example, let us consider the month of June 2020.
The start date would be 06/01/2020 — 1st of June 2020
The last date would be 06/30/2020 — 30th of June 2020
The duration would be each day. Therefore if we were to create a date-table, we should have 30 unique dates for June 2020.
Let us begin with the CALENDARAUTO() DAX function.
This function returns a table with a single column named “Date” containing a contiguous set of dates. The range of dates is calculated automatically based on data in the model.
This function has some considerations/rules associated with it, they are :
- The model MUST contain date-time values.
- It does not take into account the date values based on the calculated table and calculated column.
- The earliest date is calculated based on the MinDate
- The latest date is calculated based on the MaxDate
- If we pass an argument (an integer between 1 and 12), then our date table range “shifts” by that step.
Let us begin with our sample data.
My other post (Power Query) talks about how to connect to this data. I will go over this very quickly once again. But if you need to revisit Power Query, click the icon below to do so.
- Click get data
- Click on Excel
- Navigate to the folder where the excel file resides
- Load the data (usually, we would go with transform data as this is a good practice to ensure the quality is consistent. However, this sample data is the right format as we need it to be in).
- Navigate to the modeling tab and click on the new table
- This should open the formula bar.
- Name the table (I named it date table from calendarauto DAX and type in calendarauto(). My final formula is date table from calendarauto DAX = CALENDARAUTO() )
- This will create a date-table with a single column called date, as seen below.
- As you can see, it took the MinDate, MaxDate, and duration automatically based on the rules above.
- We did not need to pass any parameter as, by default, the parameter (fiscal year-end month) is 12 (December)





Now let us supply 3 as the argument to our function and see the “shift” in action.
- Navigate to the modeling tab and click on the new table
- This should open the formula bar.
- Name the table (I named it date table from calendarauto with 3 and type in calendarauto(3). My final formula is the date from calendar auto with 3 = CALENDARAUTO(3) )
- This will create a date-table with a single column called date, as seen below.
- As you can see, it took the MinDate, MaxDate, and duration automatically based on the rules above.
- We passed 3 as a parameter, and hence the MinDate became the end of 3rd month for the year before. Our original date started from 1/1/1995 and ended on 12/31/2025; we shifted the start date by providing 3 as the parameter. As per our rule discussed earlier, the MinDate is calculated based on the fiscal year-end month.
- The fiscal year-end month is nothing but the parameter that we provide. Since, by default, the parameter (fiscal year-end month) is 12 (December) hence the MinDate was 1/1/1995. In this case, we provided 3 as the parameter, so our start date should become 4/1/1994, and keeping the reference intact, the end date is the end of March, i.e., 3/31/2026



Our work here is not done yet. We have just a single column with date-time values. However, this is by far the most important piece if creating the entire date table. Once we have unique, non-null, date-time values (remember our rules above), we can extract all the other information out of it.
However, this is all we need to extract all the other information out of it. The steps to extract the various values such as month name, month number, day number, etc., will be covered in the next post when we demystify the calender() function since extracting the information is the same.
I hope that I was able to demystify this for you. However, if you have any concerns/queries/doubts or feel that I have made an error about this, please do not hesitate to leave a comment or send me the feedback. I will be more than happy to discuss this.
































