NDepend Blog

Improve your .NET code quality with NDepend

C# DateTime Format In A Nutshell

July 11, 2024 6 minutes read

C# DateTime Format In A-Nutshell

This article is about C# DateTime Format, which means both:

  • Obtain a date-formatted string. Use a pattern like "yyyy-MM-dd HH:mm:ss" to extract and format the year, month, day, hour, minute, and second from a DateTime instance into a string like "2024-04-25 17:07:17".
  • Parse a date formatted string to obtain back a DateTime instance.

Formats to Display a DateTime

The readonly struct System.DateTime defined in the .NET Base Class Library (BCL) is the key to handling dates and times in C#. You can experiment with various formats with this short C# program:

The following table showcases different formats applied and the output each format produces.  These formats allow for a broad customization depending on whether the need is for a simple date, a combination of date and time, or including timezone information.

dateTime.ToString("…") Result String Remarks
"dd/MM/yyyy" 25-04-2024 / the system date separator
"yyyy MMMM" 2024 April MMMM name of the month
"MMM d" Apr 25  MMM abbreviated name of the month
"ddd, dd MMM yy" Thu, 25 Apr 24 yy the year, from 00 to 99.
ddd abbreviated name of the day
"dddd, dd MMMM yyyy" Thursday, 25 April 2024 dddd name of the day
"ddd, dd MMM yyyy h:mm" Thu, 25 Apr 2024 5:07 date and time together
"yyyy-MM-dd HH:mm:ss" 2024-04-25 17:07:17 Format that can be sorted
: the system time separator
HH hour from 00 to 23
"hh:mm:ss tt" 05:07:06 PM tt the AM/PM designator.
hh hour from 00 to 11
"h:m:s t" 5:7:6 P t the A/M designator.
No leading 0 with h m s
"H:mm:ss" 17:07:06 H hour from 0 to 23
"HH:mm:ss.ff" 17:07:06.73 f for a fraction of a second
"HH:mm:ss.fffffff" 17:07:06.7301481 use as many f as needed
"HH:mm:ss UTC" 17:07:06 UTC UTC chars are not interpreted
"hh:mm:ss K" 05:07:06 +04:00  K time zone information.
"hh:mm:ss z" 05:07:06 +4  z time zone information from UTC.
"hh:mm:ss zz" 05:07:06 +04  zz time zone information from UTC
with leading zero
"HH:\\mm" 17:m7 \ is the escape character
need \\ in a C# literal string
@"HH:\mm" 17:m7 \ escape character, don’t need
\\ in a C# verbatim literal string @"…"
"HH:'mm':ss" 17:mm:06 chars in '…' are escaped
"HH:\"mm\":ss" 17:mm:06 chars in "…" are escaped

Key Format Specifiers

Here are brief explanations of some commonly used format specifiers:

  • d: Day of the month as a number from 1 through 31.
  • dd: Day of the month as a number from 01 through 31.
  • ddd: Abbreviated name of the day (Mon, Tue, etc.).
  • dddd: Full name of the day (Monday, Tuesday, etc.).
  • h: 12-hour clock hour (e.g., 4).
  • hh: 12-hour clock, with a leading 0 (e.g., 06).
  • H: 24-hour clock hour (e.g., 15).
  • HH: 24-hour clock hour, with a leading 0 (e.g., 22).
  • m: Minutes.
  • mm: Minutes with a leading zero.
  • M: Month number (e.g., 3).
  • MM: Month number with a leading zero (e.g., 04).
  • MMM: Abbreviated month name (e.g., Dec).
  • MMMM: Full month name (e.g., December).
  • s: Seconds.
  • ss: Seconds with a leading zero.
  • f: Represents the leading digit of the seconds fraction, specifically the tenths of a second, in a date and time value.
  • ff: Represents the two leading digits of the fraction of a second in a date and time value.
  • t: Abbreviated AM/PM (e.g., A or P).
  • tt: AM/PM (e.g., AM or PM).
  • yyyy: Year (e.g., 2015).
  • z: Hours offset from UTC, without leading zeros (e.g., +4).
  • zz: Hours offset from UTC, with a leading zero if it’s a single-digit hour. (e.g., +04).
  • zzz: Hours and minutes offset from UTC (e.g., +04:00).
  • K: Time zone information of a date and time value (e.g., +04:00). Unlike zzzK can adapt its output based on the kind of time being represented (local, UTC, or unspecified), potentially displaying nothing.

Character Literals

The characters FHKMdfghmstyz%:/\"' are reserved in a date and time format string. They are interpreted as formatting characters except when these special characters are used: "', and \ like in:

  • "dddd, d MMM, yyyy \"at\" HH:mm"
  • "dddd, d MMM, yyyy 'at' HH:mm"
  • "dddd, d MMM, yyyy \a\t HH:mm"

All other characters are consistently interpreted as character literals and remain unchanged in the output during a formatting operation.

Standard Format Specifiers

In addition to key format specifiers, there are some standard ones, each represented by a single letter. Here there are:

dateTime.ToString("…") Result String Remarks (*) defined for each culture
"d" 25-Apr-24 Short date pattern (*)
"D" Thursday, April 25, 2024 Long date pattern (*)
"f" Thursday, April 25, 2024 5:07 AM Full date short time (*)
"F" Thursday, April 25, 2024 5:07:08 AM Full date long time (*)
"g" 25-Apr-24 5:07 AM General date short time (*)
"G" 25-Apr-24 5:07:08 AM General date long time (*)
"m" or "M" April 25 Month/day pattern (*)
"o" or "O" 2024-04-25T05:07:08.7300000+04:00 Round-trip date/time pattern (ISO 8601)
"s" 2024-04-25T05:07:08 Sortable date/time pattern (ISO 8601)
"r" or "R" Thu, 25 Apr 2024 05:07:08 GMT RFC1123 pattern
"t" 5:07 AM Short time pattern (*)
"T" 5:07:08 AM Long time pattern (*)
"u" 2024-04-25 05:07:08Z Universal sortable date/time pattern
"U" Thursday, April 25, 2024 1:07:08 AM Universal full date/time pattern
"y" or "Y" April 2024 Year month pattern (*)
Any other single character Throws a FormatException at runtime

The Role of the Culture in DateTime Formatting

Up to this point, all our experiments of displaying DateTime values have been relying on the English (United States) culture. Actually, the current thread’s culture determines how a date is formatted. Below is a sample program that illustrates this concept:

Also, each culture has its own pattern for formatting a DateTime. This is demonstrated by this program:

As a reminder 🙂

A map of all countries that use the MMDDYYYY date format

It may seem acceptable to overlook cultural settings when working with DateTime formats that aren’t being parsed from strings. However, as a professional developer, you undoubtedly recognize the necessity of parsing dates from strings at some point in your work.

Parsing a Formatted DateTime String

The methods DateTime.ParseExact() or DateTime.TryParseExact(), will be your friends when parsing a DateTime. The following sample program showcases its use, carefully considering cultural nuances and time zone information:

You can still try to parse a date time from a string without specifying a format and a culture but this would make your code very fragile. This can lead to bugs that are hard to detect, especially in environments where the application might be running under different cultural settings.

DateTime Formatting in C#: Best Practices

The main advice is: Don’t use a number for a month because it leads to confusion! Which date is "05 04 2025"? You can use instead "dd MMM yyyy" that leads to "05 Apr 2025". But with such an unambiguous format, we have to take account of the culture because of the month’s abbreviated name.

Other common best practices are:

  • Consistency is Key: Always use a consistent DateTime format across your application unless the context specifically demands variation, like the need to sort formatted dates.
  • Localization Matters: Consider the local date and time formats of your application’s users. Localization methods shown in this post help render DateTime in a culturally appropriate manner.
  • Sorting Date Might Matter: If formatted dates need to be sorted, this popular format needs to be used: yyyy-MM-dd
  • Performance: Note that parsing and formatting DateTime is a computationally expensive operation. Format dates only when necessary. .NET 8 improved DateTime formatting performance. However, if performance is a priority and the format is hardcoded, you can develop your own highly efficient formatting and parsing code, similar to what we did in NDepend. If you choose this route, tools like ChatGPT or Copilot can help by generating much of the necessary code for you.
  • NodaTime for Advanced Scenario: The .NET community is fortunate to have access to NodaTime, a library developed by recognized expert and writer Jon Skeet from the Java library Joda Time. If date and time are central to your application, NodaTime is worth exploring.

By mastering DateTime formatting, you can ensure that your applications handle date and time data efficiently and effectively, tailored to the needs of various use cases and locales. Let’s conclude with this meme that always brings a smile to my face 🙂

DateTime Format Humour