Display Datetime in a Specific Format: CONVERT and FORMAT

To display datetime in a specific format, use CONVERT with a style number, or FORMAT with a pattern. Both turn a date into text. They differ in speed, in how you read them, and in the mistakes they invite.

Gouache painting of two shelves holding the same three jars in opposite orders, the short jar on the top shelf painted red

CONVERT and Style Numbers

Every example here uses one fixed value, so the results never change. The value is 6 October 2026 at 2:35:09 PM, with 123 milliseconds. CONVERT takes a target type, the value and a style number. The style decides the layout. For the date styles shown here, styles below 100 give a two digit year. The same style plus 100 gives four digits.

DECLARE @d datetime2(3) = '2026-10-06T14:35:09.123';
SELECT s.Style, s.Layout, CONVERT(varchar(30), @d, s.Style) AS Result
FROM (VALUES (1, 'mm/dd/yy'), (3, 'dd/mm/yy'), (5, 'dd-mm-yy'), (101, 'mm/dd/yyyy'), (103, 'dd/mm/yyyy'), (105, 'dd-mm-yyyy'),
             (106, 'dd mon yyyy'), (107, 'Mon dd, yyyy'), (108, 'hh:mi:ss'), (110, 'mm-dd-yyyy'), (112, 'yyyymmdd'),
             (120, 'yyyy-mm-dd hh:mi:ss'), (121, 'yyyy-mm-dd hh:mi:ss.mmm'), (126, 'ISO 8601')) AS s(Style, Layout)
ORDER BY s.Style;
StyleLayoutResult
1mm/dd/yy10/06/26
3dd/mm/yy06/10/26
5dd-mm-yy06-10-26
101mm/dd/yyyy10/06/2026
103dd/mm/yyyy06/10/2026
105dd-mm-yyyy06-10-2026
106dd mon yyyy06 Oct 2026
107Mon dd, yyyyOct 06, 2026
108hh:mi:ss14:35:09
110mm-dd-yyyy10-06-2026
112yyyymmdd20261006
120yyyy-mm-dd hh:mi:ss2026-10-06 14:35:09
121yyyy-mm-dd hh:mi:ss.mmm2026-10-06 14:35:09.123
126ISO 86012026-10-06T14:35:09.123

Styles 101 and 103 differ only in the order of day and month. The text 06/10/2026 means two different dates to an American and a European reader. That’s why I prefer a layout with the month name, such as 106. An ISO layout such as 120 or 126 works too. Neither can be misread. Style 112, with no separators, sorts correctly as text.

Give the target type enough room. A varchar(30) holds every result above. A varchar(10) would cut 2026-10-06 14:35:09 without a word.

FORMAT and Patterns

To display datetime with FORMAT, you pass a pattern instead of a number. The pattern uses letters, and the case of each letter matters. The next query uses a correct pattern and a wrong one. The wrong one is a pattern that many scripts copy.

DECLARE @d datetime2(3) = '2026-10-06T14:35:09.123';
SELECT FORMAT(@d, 'dd MMM yyyy HH:mm:ss.fff', 'en-US') AS Correct,
       FORMAT(@d, 'dd mon yyyy HH:m:ss:mmm', 'en-US') AS WrongCase;
CorrectWrongCase
06 Oct 2026 14:35:09.12306 35on 2026 14:35:09:35

The wrong pattern prints 35 in three places. A capital M means the month. A lowercase m means the minute. So mon became the minute followed by the letters o and n. Use MMM for the month name and mm for minutes. HH is a 24 hour clock, and hh or h is a 12 hour clock. Use fff for milliseconds. Note that mmm isn’t milliseconds.

DECLARE @d datetime2(3) = '2026-10-06T14:35:09.123';
SELECT FORMAT(@d, 'MM/dd/yyyy h:mm tt', 'en-US') AS UsStyle,
       FORMAT(@d, 'dd MMMM yyyy', 'de-DE') AS German,
       FORMAT(@d, N'"Current Time is "dddd MMMM dd, yyyy', 'en-US') AS WithText;
UsStyleGermanWithText
10/06/2026 2:35 PM06 Oktober 2026Current Time is Tuesday October 06, 2026

Three things FORMAT does well. It writes AM and PM in any layout you choose with tt. CONVERT has only the fixed styles 0, 100 and 109 for that. It follows a culture, so the German example prints the month name in German. And it lets you add text in double quotes inside the pattern.

Quick card titled Display Datetime in T-SQL: Style 101: mm/dd/yyyy, style 103: dd/mm/yyyy; Month name: style 106 prints 06 Oct 2026; ISO: styles 120 and 126; FORMAT: MM is the month, mm is the minute; Size: use varchar(30) so no result is cut. Tip: Keep the column a date type and format at the edge

Which One to Use

The price of that flexibility is speed. The script below builds 200,000 dates in a temporary table, then formats each one both ways and prints the milliseconds. Your numbers will differ. The proportion is what matters.

SELECT TOP (200000) DATEADD(MINUTE, n, '2026-01-01') AS d INTO #dates
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n FROM sys.all_objects AS a CROSS JOIN sys.all_objects AS b) AS nums;
GO
DECLARE @t0 datetime2(3) = SYSDATETIME(), @x int;
SELECT @x = SUM(LEN(CONVERT(varchar(10), d, 120))) FROM #dates;
DECLARE @t1 datetime2(3) = SYSDATETIME();
SELECT @x = SUM(LEN(FORMAT(d, 'yyyy-MM-dd', 'en-US'))) FROM #dates;
DECLARE @t2 datetime2(3) = SYSDATETIME();
SELECT DATEDIFF(MILLISECOND, @t0, @t1) AS ConvertMs, DATEDIFF(MILLISECOND, @t1, @t2) AS FormatMs;
DROP TABLE #dates;

In three runs on the test server, CONVERT needed about 110 milliseconds and FORMAT needed about 1,100 to 1,300. FORMAT took roughly ten times as long. For one value in a report header, that is nothing. For a column of a million rows, it is a real cost. Use CONVERT for bulk work. Use FORMAT for a 12 hour layout of your choice, a culture or text inside the pattern.

Questions That Come Up

Two requests keep returning. The first is converting a text date to a real date. An example is 25-02-14, day first with a two digit year. Pass the style that matches the text. Style 5 is day, month and year with dashes. The second is turning 11:30 AM, stored as text, into a time. TRY_CONVERT parses it and returns NULL when the text isn’t a time.

SELECT CONVERT(date, '25-02-14', 5) AS DayFirstTwoDigitYear, TRY_CONVERT(time(0), '11:30 AM') AS ParsedTime;
DayFirstTwoDigitYearParsedTime
2014-02-2511:30:00

Note the year. SQL Server read 14 as 2014. It treats two digit years from 00 to 49 as 20xx, and 50 to 99 as 19xx. A four digit year in the source leaves no doubt.

Parsing Depends on the Session

How you display datetime is only half of the story. When SQL Server reads text such as 03/04/2026, it must guess the order. The session’s DATEFORMAT decides, and it follows the login’s language. The same text gives two different dates. A new connection returns to the login’s default.

SET DATEFORMAT dmy;
SELECT CAST('03/04/2026' AS date) AS AsDmy;
SET DATEFORMAT mdy;
SELECT CAST('03/04/2026' AS date) AS AsMdy;
AsDmy
2026-04-03
AsMdy
2026-03-04

The cure is to say which order you mean. CONVERT(date, '03/04/2026', 101) reads the text as month first, and the style wins whatever the session says. Better still, pass dates as yyyymmdd, or as ISO 8601 with a T, such as 2026-10-06T14:35:09. Those layouts read the same under every setting.

You could argue that all this formatting belongs in the application, not in T-SQL. It does. Keep the column a date type and send the raw value. Let the application format it for each user’s culture. Use T-SQL formatting for exports, file names and messages that stay inside the database.

What to Remember

Use CONVERT with a style for speed and FORMAT for a 12 hour layout of your choice or a culture. Remember that MM is the month and mm is the minute. Size the target type for the longest result, and pass a style whenever you convert text to a date. A date stored as a string can’t be sorted or compared as a date, so keep the type.

A date is not a string, it is a value you format when someone reads it.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL DateTime, SQL Function, SQL Scripts, SQL String
Previous Post
SQL SERVER – Using RAND() in User Defined Functions (UDF)
Next Post
SQL SERVER – Removing Leading Zeros From Column in Table – Part 2

Related Posts

12 Comments. Leave new

  • Thank you – nice explanation

    Reply
  • Ahmadreza Atighechi
    May 14, 2013 11:07 am

    I’m afraid in order to show millisecond we should use fff rather than mmm

    Reply
  • SELECT FORMAT ( GETDATE(), ‘dd mon yyyy HH:m:ss:mmm’, ‘en-US’ ) AS DateConvert;

    Typo error.

    Reply
  • Hi,
    (SELECT CONVERT(VARCHAR(30),it.StartDate) )[start] will return date as Jun 17 2013 2:00PM and ( SELECT CONVERT(VARCHAR(30),it.EndDate,101))[end] will return date as 06/17/2013 but i need date format like 06/17/2013 2:00 PM. Can you please help me in this?

    Reply
  • Hi,
    ( SELECT CONVERT(VARCHAR(30),it.EndDate,101))[end] will return date as 06/17/2013 and (SELECT CONVERT(VARCHAR(30),it.StartDate) )[start] will return date as Jun 17 2013 2:00PM and i need date in the following format 06/17/2013 2:00 PM(“/” is important) . Can you please help me on this

    Reply
  • got the answer.
    SELECT (CONVERT(VARCHAR(30),it.EndDate,101) +’ ‘ +
    CONVERT(VARCHAR(30),it.EndDate,8)) AS end

    Reply
  • Hi pinal

    i want to have a date range list in a drop down for reports like as follows
    Today
    Yesterday
    Before Two Days
    Current Week
    Last Week
    Current Month
    Last Month
    Last 3 Months
    Current Year
    Last Year
    First Quater
    Second Quater
    Third Quater
    Fourth Quater

    Reply
    • Hi Pinal

      ITS VERY URGENT

      I want to convert ’25-02-14′ (dd-mm-yy) format to ‘2014-02-25’ (yyyy-mm-dd).

      I’m trying of many methods but I could not able to get through.

      Waiting for your reply.

      Thanks & Regards
      Madhu.R

      Reply
  • Balvant Ramani
    May 6, 2014 11:59 am

    My table has filed with data type datetime…. when i update it it gives conversion error .. i update it via procedure.. i pass parameter to procedure.. and update table.. pls give solution.

    Reply
  • SELECT CONVERT(DATE,STUFF(’25-02-14′,7,0,’20’), 105) AS [DATEFORMAT]

    Reply
  • My table contains nvarchar(50) field which contains data like “11:30 AM “, i want to convert it to time

    Reply
  • I have an SQL related Problem in My Stored Proc Where Do I Ask by attaching a Notepad Data?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.