13. DAX: Data Analysis Expressions
13.16 Time Intelligence
Simple bhashet sangaycha tar, time intelligence functions compare values across periods. Requirements: a proper date table marked as a date table (Module 11), related to the fact table, and the date column from the Date table used in the functions.
Year-to-date (YTD), QTD, MTD
Sales YTD = TOTALYTD([Total Sales], 'Date'[Date])
-- Same result using CALCULATE + DATESYTD
Sales YTD v2 = CALCULATE([Total Sales], DATESYTD('Date'[Date]))
-- Indian financial year (April–March): year ends on 31 March
Sales FYTD = TOTALYTD([Total Sales], 'Date'[Date], "3/31")
Orders QTD = TOTALQTD([Total Orders], 'Date'[Date])
Orders MTD = TOTALMTD([Total Orders], 'Date'[Date])
The optional year-end argument is a text date (month/day). Its interpretation can depend on locale; "3/31" is the common way to express 31 March.
Previous year and previous period
Sales LY = CALCULATE([Total Sales], SAMEPERIODLASTYEAR('Date'[Date]))
Sales LY (DATEADD) = CALCULATE([Total Sales], DATEADD('Date'[Date], -1, YEAR))
Orders Previous Month = CALCULATE([Total Orders], DATEADD('Date'[Date], -1, MONTH))
Orders Previous Week = CALCULATE([Total Orders], DATEADD('Date'[Date], -7, DAY))
-- Full previous year, regardless of which month is selected
Sales Full Prev Year = CALCULATE([Total Sales], PARALLELPERIOD('Date'[Date], -1, YEAR))
Sales LY YTD = CALCULATE([Sales YTD], SAMEPERIODLASTYEAR('Date'[Date]))
| Function | Returns | Example with March 2025 selected |
|---|---|---|
SAMEPERIODLASTYEAR |
Same dates shifted back one year | March 2024 |
DATEADD(dates, -1, YEAR) |
Dates shifted by any number of days/months/quarters/years | March 2024 |
DATEADD(dates, -1, MONTH) |
Shifted back one month | February 2025 |
PARALLELPERIOD(dates, -1, YEAR) |
The complete previous period(s) at the chosen level | Jan–Dec 2024 |
DATESYTD(dates) |
Dates from start of year to last visible date | 1 Jan – 31 Mar 2025 |
Festivals move every year
Diwali and Ganeshotsav fall on different calendar dates each year. SAMEPERIODLASTYEAR compares the same dates, so October this year may be compared with a non-festival October last year – growth will look unusually high or low. For festival analysis, compare festival days with festival days using the Festival column from Module 5:
Festival Orders = CALCULATE([Total Orders], 'Date'[Is Festival Day] = TRUE())
-- Use in a visual or card filtered to one Year
Diwali Orders LY =
VAR PrevYear = MAX('Date'[Year]) - 1
RETURN
CALCULATE(
[Total Orders],
'Date'[Festival] = "Diwali",
'Date'[Year] = PrevYear
)
Year-over-Year and Month-over-Month growth %
YoY Growth % =
VAR CurrentSales = [Total Sales]
VAR PreviousSales = [Sales LY]
RETURN
IF(
NOT ISBLANK(CurrentSales) && NOT ISBLANK(PreviousSales),
DIVIDE(CurrentSales - PreviousSales, PreviousSales)
)
MoM Orders Growth % =
DIVIDE([Total Orders] - [Orders Previous Month], [Orders Previous Month])
Running total (cumulative)
Running Total Orders =
CALCULATE(
[Total Orders],
FILTER(
ALL('Date'[Date]),
'Date'[Date] <= MAX('Date'[Date])
)
)
For each point on the axis, it counts orders from the first date in the model up to the last visible date. A YTD measure is a running total (आतापर्यंतची एकत्रित बेरीज) that restarts every year. (Because orders are counted with DISTINCTCOUNT, each Order ID is counted once even across dates.)
Moving (rolling) average
-- Average of the last 3 months' sales (monthly level visual)
Sales 3M Moving Avg =
VAR Period =
DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -3, MONTH)
RETURN
CALCULATE(
AVERAGEX(VALUES('Date'[Year Month]), [Total Sales]),
Period
)
-- 7-day moving average of daily orders (daily level visual)
Orders 7D Moving Avg =
CALCULATE(
AVERAGEX(VALUES('Date'[Date]), [Total Orders]),
DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -7, DAY)
)
DATESINPERIOD(dates, start_date, number_of_intervals, interval) returns a continuous set of dates going backwards (negative number) or forwards from the start date. Moving averages smooth out short-term ups and downs (for example weekend peaks in grocery orders) so the trend is easier to see.
Time intelligence needs continuous dates
If you use the date column from the Orders table instead of the Date table, results can be wrong karan the fact table may have gaps (days without orders). Always use 'Date'[Date].
Ghabru naka, time intelligence suruvatila khup functions vattat. Pan sagle ekach niyamavar chaltat – marked Date table.
Ravindra Bagale's Tip
Remember one thing: time intelligence fails silently when the Date table is not marked, has gaps, or is related through a DateTime column. Before writing SAMEPERIODLASTYEAR or TOTALYTD, check these three things. For an April–March financial year, pass the year-end date "31/3" to TOTALYTD. Practise, and it will feel very easy.
Ravindra Bagale's Tip – मराठी
एक गोष्ट लक्षात ठेवा: Date table mark केलेला नसेल, त्यात gaps असतील, किंवा तो DateTime column ने relate केलेला असेल तर time intelligence काहीही न सांगता fail होतं. SAMEPERIODLASTYEAR किंवा TOTALYTD लिहिण्याआधी या तीन गोष्टी तपासा. April–March financial year साठी TOTALYTD ला year-end date "31/3" द्या. Practice करा, मग एकदम सोपं वाटेल.
Ravindra Bagale's Tip – हिंदी
एक बात याद रखो: Date table mark न हो, उसमें gaps हों, या वह DateTime column से relate हो तो time intelligence चुपचाप fail हो जाता है. SAMEPERIODLASTYEAR या TOTALYTD लिखने से पहले ये तीन बातें check करो. April–March financial year के लिए TOTALYTD को year-end date "31/3" दो. Practice करो, फिर बहुत आसान लगेगा.