Creating a calendar

One of the most frequently asked questions regarding the calendar required to use time intelligence features is, is it better to create it external to Power BI? Or in the query editor? Or maybe with DAX?

In this scenario we are going to create a complete calendar in DAX, including the number and name of the month, quarter, day of the week, etc.

To begin, we create the basic calendar table using the CALENDARAUTO function. This function creates a table with a single column with a sequence of dates covering all the dates that appear in our data set, by default from January 1 of the first year to December 31 of the last year:

Calendar = CALENDARAUTO()

Calendar created with CALENDARAUTO

However, we want to add other fields to this basic table, for which we are going to use the following DAX functions (note in the image above that the field created is named "Date"):

  • To create the year: YEAR
  • To create the month number: MONTH
  • To create the day number: DAY

We are going to add these new fields to the basic table using the ADDCOLUMNS function:

Calendar = 
    ADDCOLUMNS(
        CALENDARAUTO();
        "Year"; YEAR([Date]);
        "Month"; MONTH([Date]);
        "Day"; DAY([Date])
    )

Fields for the year, month number, and day of the month

The names for the month and the day of the week can be created with the FORMAT function, and the week number and the day of the week number with the WEEKNUM and WEEKDAY functions, respectively:

Calendar = 
    ADDCOLUMNS(
        CALENDARAUTO();
        "Year"; YEAR([Date]);
        "Month"; MONTH([Date]);
        "Month Name"; FORMAT([Date]; "MMMM");
        "Week #"; WEEKNUM([Date]);
        "Day"; DAY([Date]);
        "Week Day"; WEEKDAY([Date]);
        "Day Name"; FORMAT([Date]; "DDDD")
    )

Fields for the name of the month and the day, the number of the week and the number of the day of the week

Finally, to obtain the quarter number we can use the formula:

CEILING(MONTH([Date])/3,1)

...which calculates the nearest integer equal to or greater than the month divided by 3 (with the CEILING function).

If we also wanted to have the equivalent preceded by a "Q", we can again resort to the FORMAT function and the & operator that allows us to concatenate text strings:

Calendar = 
    ADDCOLUMNS(
        CALENDARAUTO();
        "Year"; YEAR([Date]);
        "Quarter #"; CEILING(MONTH([Date])/3;1);
        "Quarter"; "Q" & FORMAT(CEILING(MONTH([Date])/3;1); "#");
        "Month"; MONTH([Date]);
        "Month Name"; FORMAT([Date]; "MMMM");
        "Week #"; WEEKNUM([Date]);
        "Day"; DAY([Date]);
        "Week Day"; WEEKDAY([Date]);
        "Day Name"; FORMAT([Date]; "DDDD")
    )

Fields for the quarter
Difficulty
Low
Submitted by admin on Sun, 07/07/2019 - 18:20