A Quick Look at SQL Server’s DATETRUNC() Function

SQL Server 2022 introduced the DATETRUNC() function, which makes working with date and time values much easier. It trims (or “truncates”) a date/time value down to a specified part (like year, month, or week) while setting all smaller units to their starting value. This helps avoid the common hack of mixing DATEADD() and DATEDIFF() just to snap a timestamp to the beginning of a period.

In this article we’ll look at some examples that demonstrate how it works.

A Simple Example

Let’s use the DATETRUNC() function to truncate a date/time value to the day:

SELECT DATETRUNC(day, '2025-08-24 13:47:29.123');

Result:

2025-08-24 00:00:00.0000000

That’s it. All we did was tell SQL Server something like “Take this value and cut it down to the start of the day”. The time portion is reset to midnight, because that’s the smallest unit inside a day.

Let’s try a different unit:

SELECT DATETRUNC(month, '2025-08-24 13:47:29.123');

Result:

2025-08-01 00:00:00.0000000

This snaps the timestamp to the very start of the month, which is August 1st at midnight.

Supported Dateparts

DATETRUNC() works with a variety of date parts:

DatepartAbbreviationsDescription / Notes
yearyy, yyyyTruncates to the start of the year
quarterqq, qTruncates to the first day of the quarter
monthmm, mTruncates to the first day of the month
dayofyeardy, ySame as day in that it truncates to the start of the day (removes the time component)
daydd, dSame as dayofyear (truncates to the start of the day)
weekwk, wwTruncates to the first day of the week, as defined by the session’s @@DATEFIRST setting
iso_weekisowk, isowwTruncates to the first day of the ISO week (Monday, per ISO-8601)
hourhhTruncates to the start of the hour
minutemi, nTruncates to the start of the minute
secondss, sTruncates to the start of the second
millisecondmsTruncates to the millisecond precision (rounding down)
microsecondmcsTruncates to the microsecond precision (rounding down)

Each one zeroes out anything smaller than that unit.

Microsoft’s documentation explicitly states that:

The weekday, timezoneoffset, and nanosecond T-SQL dateparts aren’t supported for DATETRUNC.

Comparing Dateparts

Let’s check each of the above dateparts with DATETRUNC():

DECLARE @dt DATETIME2(7) = '2025-08-24 13:47:29.1234567';
SELECT 'Year', DATETRUNC(year, @dt);
SELECT 'Quarter', DATETRUNC(quarter, @dt);
SELECT 'Month', DATETRUNC(month, @dt);
SELECT 'Week', DATETRUNC(week, @dt);
SELECT 'Iso_week', DATETRUNC(iso_week, @dt);
SELECT 'DayOfYear', DATETRUNC(dayofyear, @dt);
SELECT 'Day', DATETRUNC(day, @dt);
SELECT 'Hour', DATETRUNC(hour, @dt);
SELECT 'Minute', DATETRUNC(minute, @dt);
SELECT 'Second', DATETRUNC(second, @dt);
SELECT 'Millisecond', DATETRUNC(millisecond, @dt);
SELECT 'Microsecond', DATETRUNC(microsecond, @dt);

Output:

---- --------------------------------------
Year 2025-01-01 00:00:00.0000000

------- --------------------------------------
Quarter 2025-07-01 00:00:00.0000000

----- --------------------------------------
Month 2025-08-01 00:00:00.0000000

---- --------------------------------------
Week 2025-08-24 00:00:00.0000000

-------- --------------------------------------
Iso_week 2025-08-18 00:00:00.0000000

--------- --------------------------------------
DayOfYear 2025-08-24 00:00:00.0000000

--- --------------------------------------
Day 2025-08-24 00:00:00.0000000

---- --------------------------------------
Hour 2025-08-24 13:00:00.0000000

------ --------------------------------------
Minute 2025-08-24 13:47:00.0000000

------ --------------------------------------
Second 2025-08-24 13:47:29.0000000

----------- --------------------------------------
Millisecond 2025-08-24 13:47:29.1230000

----------- --------------------------------------
Microsecond 2025-08-24 13:47:29.1234560

How Weeks Behave (and @@DATEFIRST)

Weeks are where things get interesting. The function respects SQL Server’s @@DATEFIRST setting, which defines the first day of the week (1 = Monday, 7 = Sunday, etc.). The above example used my default @@DATEFIRST setting value, which was 7.

We can check our @@DATEFIRST value with a simple SELECT statement:

SELECT @@DATEFIRST;

Output:

7

Let’s see what happens when we change our @@DATEFIRST value. First, we’ll explicitly set it to 7:

-- Assume @@DATEFIRST is 7 (Sunday)
SET DATEFIRST 7;
SELECT DATETRUNC(week, '2025-08-24 13:47:29.123') AS WeekStartSunday;

Result:

WeekStartSunday                       
--------------------------------------
2025-08-24 00:00:00.0000000

Since August 24, 2025, is a Sunday, and Sunday is considered the first day of the week, truncation returns that same date at midnight.

Now, let’s change the @@DATEFIRST setting:

-- Switch to Monday as first day of the week
SET DATEFIRST 1;
SELECT DATETRUNC(week, '2025-08-24 13:47:29.123') AS WeekStartMonday;

Result:

WeekStartMonday                       
--------------------------------------
2025-08-18 00:00:00.0000000

With Monday as the first day of the week, the timestamp is snapped back to the Monday of that week instead.

This can cause very different results depending on your environment, so always be clear about what @@DATEFIRST is set to if you’re using DATETRUNC() with weeks.

Impact of Data Type Precision

One thing to keep in mind: DATETRUNC() doesn’t control precision – the data type does. The function always returns the same type as the input, so whatever granularity that type supports is what you’ll see in the result.

For example:

DECLARE @dt  DATETIME     = '2025-08-24 13:47:29.997';
DECLARE @dt2 DATETIME2(7) = '2025-08-24 13:47:29.9971234';
DECLARE @dt3 SMALLDATETIME = '2025-08-24 13:47:29';

SELECT 
    DATETRUNC(SECOND, @dt)  AS DT_Second,
    DATETRUNC(SECOND, @dt2) AS DT2_Second,
    DATETRUNC(SECOND, @dt3) AS DT3_Second;

Result:

DT_Second               DT2_Second                             DT3_Second         
----------------------- -------------------------------------- -------------------
2025-08-24 13:47:29.000 2025-08-24 13:47:29.0000000 2025-08-24 13:47:00

Here’s why:

  • datetime: Precision is ~3 milliseconds, stored to milliseconds only.
  • datetime2(7): Supports up to 100ns precision, so the display goes to 7 fractional digits.
  • smalldatetime: Only accurate to the minute, so seconds are discarded entirely.

So DATETRUNC() just zeroes out everything below the requested unit. How many digits you see (or even whether seconds are stored at all) depends on the column’s data type, not the truncation function.

Doing it Without DATETRUNC()

Before DATETRUNC() came along, truncating a datetime to the start of a month might involve something like:

SELECT DATEADD(day, 1, EOMONTH(@Date, -1));

Not too bad, but certainly more complex than doing it with DATETRUNC(). DATETRUNC() not only makes your code more readable, but also less error-prone. It’s easier to understand at a glance, which is especially helpful when weeks and @@DATEFIRST are involved.