Back to Home

C# DateTime Format Examples: yyyy-MM-dd, ISO 8601, and More

In C#, you can format DateTime values using format strings with ToString() or string interpolation. The easiest way to get started is with a few practical patterns that you can copy into your own code.

Quick cheat sheet

C# Example Code
DateTime value = new(2024, 3, 15, 14, 30, 45);

Console.WriteLine(value.ToString("yyyy-MM-dd"));          // 2024-03-15
Console.WriteLine(value.ToString("yyyyMMdd"));            // 20240315
Console.WriteLine(value.ToString("yyyy-MM-ddTHH:mm:ss")); // 2024-03-15T14:30:45
Console.WriteLine(value.ToString("HH:mm:ss"));            // 14:30:45
Console.WriteLine(value.ToString("hh:mm tt"));            // 02:30 PM

Use yyyy-MM-dd for sortable filenames, yyyy-MM-ddTHH:mm:ss for ISO 8601 timestamps, and HH:mm:ss for 24-hour log output.

Custom format strings are case-sensitive: MM is month, mm is minutes, HH is 24-hour time, and hh is 12-hour time.

C# Example Code
using System;

DateTime now = DateTime.Now;
DateTime specificDate = new DateTime(2024, 3, 15, 14, 30, 45);

// Standard format specifiers
Console.WriteLine("Standard Formats:");
Console.WriteLine($"Short date (d): {now:d}");
Console.WriteLine($"Long date (D): {now:D}");
Console.WriteLine($"Short time (t): {now:t}");
Console.WriteLine($"Long time (T): {now:T}");
Console.WriteLine($"Full date/time (F): {now:F}");
Console.WriteLine($"General (G): {now:G}");

// Custom format strings
Console.WriteLine("\nCustom Formats:");
Console.WriteLine($"yyyy-MM-dd: {specificDate:yyyy-MM-dd}");
Console.WriteLine($"MM/dd/yyyy: {specificDate:MM/dd/yyyy}");
Console.WriteLine($"dd-MMM-yyyy: {specificDate:dd-MMM-yyyy}");
Console.WriteLine($"HH:mm:ss: {specificDate:HH:mm:ss}");
Console.WriteLine($"hh:mm tt: {specificDate:hh:mm tt}");

// Combining date and time
Console.WriteLine("\nCombined:");
Console.WriteLine($"ISO 8601: {specificDate:yyyy-MM-ddTHH:mm:ss}");
Console.WriteLine($"Custom: {specificDate:MMMM dd, yyyy 'at' h:mm tt}");

// Day and month names
Console.WriteLine("\nNames:");
Console.WriteLine($"Day of week: {now:dddd}");
Console.WriteLine($"Month name: {now:MMMM}");
Console.WriteLine($"Abbreviated: {now:ddd, MMM dd}");

// Using ToString method
Console.WriteLine("\nUsing ToString:");
Console.WriteLine(now.ToString("yyyy-MM-dd"));
Console.WriteLine(now.ToString("h:mm:ss tt"));

Common mistakes

  • mm is minutes, while MM is the month number.
  • hh is 12-hour time, while HH is 24-hour time.
  • Use yyyy-MM-dd or yyyyMMdd for filenames to avoid slashes and locale issues.

Standard Format Specifiers Reference

SpecifierDescriptionExample (2024-03-15 14:30:45, en-US)
dShort date3/15/2024
DLong dateFriday, March 15, 2024
tShort time2:30 PM
TLong time2:30:45 PM
fFull date/time, short timeFriday, March 15, 2024 2:30 PM
FFull date/time, long timeFriday, March 15, 2024 2:30:45 PM
gGeneral, short time3/15/2024 2:30 PM
GGeneral, long time3/15/2024 2:30:45 PM
M / mMonth and dayMarch 15
Y / yYear and monthMarch 2024
sSortable, no timezone2024-03-15T14:30:45
O / oRound-trip ISO 86012024-03-15T14:30:45.0000000
R / rRFC 1123Fri, 15 Mar 2024 14:30:45 GMT
uUniversal sortable2024-03-15 14:30:45Z

Custom Format Specifiers Reference

SpecifierMeaningExample
d / ddDay, no/with leading zero5 / 05
ddd / ddddAbbreviated / full day nameFri / Friday
M / MMMonth number, no/with leading zero3 / 03
MMM / MMMMAbbreviated / full month nameMar / March
yy / yyyy2-digit / 4-digit year24 / 2024
h / hh12-hour clock, no/with leading zero2 / 02
H / HH24-hour clock, no/with leading zero14 / 14
m / mmMinutes, no/with leading zero5 / 05
s / ssSeconds, no/with leading zero9 / 09
fffMilliseconds (3 digits)045
ttAM/PM designatorPM
zzzUTC offset+01:00
'text'Literal text in single quotesat, on, …
C# Example Code
DateTime dt = new DateTime(2024, 3, 15, 14, 30, 45);

Console.WriteLine(dt.ToString("yyyy-MM-dd"));                  // 2024-03-15
Console.WriteLine(dt.ToString("dd/MM/yyyy"));                  // 15/03/2024
Console.WriteLine(dt.ToString("MM/dd/yyyy"));                  // 03/15/2024
Console.WriteLine(dt.ToString("dd-MMM-yyyy"));                 // 15-Mar-2024
Console.WriteLine(dt.ToString("MMMM dd, yyyy"));               // March 15, 2024
Console.WriteLine(dt.ToString("yyyyMMdd"));                    // 20240315
Console.WriteLine(dt.ToString("HH:mm:ss"));                    // 14:30:45
Console.WriteLine(dt.ToString("hh:mm tt"));                    // 02:30 PM
Console.WriteLine(dt.ToString("yyyy-MM-dd HH:mm:ss"));         // 2024-03-15 14:30:45
Console.WriteLine(dt.ToString("yyyy-MM-ddTHH:mm:ss"));         // 2024-03-15T14:30:45

// Literal text in single quotes
Console.WriteLine(dt.ToString("MMMM dd, yyyy 'at' h:mm tt")); // March 15, 2024 at 2:30 PM
Console.WriteLine(dt.ToString("dddd, MMMM d"));                // Friday, March 15

ParseExact and TryParseExact

Use ParseExact / TryParseExact when you know the exact format of the input string. They avoid the ambiguity of DateTime.Parse with culture-dependent inputs.

C# Example Code
using System.Globalization;

// ParseExact — throws FormatException if format doesn't match
string input = "15-03-2024";
DateTime parsed = DateTime.ParseExact(input, "dd-MM-yyyy", CultureInfo.InvariantCulture);
Console.WriteLine(parsed.ToString("D")); // Friday, March 15, 2024

// TryParseExact — safe version, returns false on failure
string userInput = "2024/03/15 14:30";
if (DateTime.TryParseExact(userInput, "yyyy/MM/dd HH:mm",
    CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result))
{
    Console.WriteLine($"Parsed: {result:F}");
}
else
{
    Console.WriteLine("Invalid format");
}

// Accept multiple formats
string[] formats = { "dd/MM/yyyy", "MM/dd/yyyy", "yyyy-MM-dd" };
DateTime.TryParseExact("01/03/2024", formats,
    CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime multi);
Console.WriteLine($"Parsed: {multi:D}"); // Friday, March 01, 2024

Culture-Specific Formatting

Output differs by culture. Use CultureInfo.InvariantCulture for storage and logs; use the user's locale for display.

C# Example Code
using System.Globalization;

DateTime dt = new DateTime(2024, 3, 15, 14, 30, 0);

Console.WriteLine(dt.ToString("d", new CultureInfo("en-US"))); // 3/15/2024
Console.WriteLine(dt.ToString("d", new CultureInfo("en-GB"))); // 15/03/2024
Console.WriteLine(dt.ToString("d", new CultureInfo("de-DE"))); // 15.03.2024
Console.WriteLine(dt.ToString("D", new CultureInfo("fr-FR"))); // vendredi 15 mars 2024
Console.WriteLine(dt.ToString("D", new CultureInfo("ja-JP"))); // 2024年3月15日

// InvariantCulture for storage (always consistent, locale-independent)
string stored = dt.ToString("o", CultureInfo.InvariantCulture);
Console.WriteLine(stored); // 2024-03-15T14:30:00.0000000

DateTimeOffset — Timezone-Aware Dates

Use DateTimeOffset instead of DateTime when your app spans multiple timezones. It stores the UTC offset alongside the value.

C# Example Code
DateTimeOffset utc   = DateTimeOffset.UtcNow;
DateTimeOffset local = DateTimeOffset.Now;

Console.WriteLine(utc.ToString("o"));    // 2024-03-15T13:30:45.0000000+00:00
Console.WriteLine(local.ToString("o"));  // 2024-03-15T14:30:45.0000000+01:00

// Create with explicit offset
DateTimeOffset eastern = new DateTimeOffset(2024, 3, 15, 9, 0, 0, TimeSpan.FromHours(-5));
Console.WriteLine(eastern.ToString("o")); // 2024-03-15T09:00:00.0000000-05:00

// Convert to another timezone
TimeZoneInfo pacific = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
DateTimeOffset pacificTime = TimeZoneInfo.ConvertTime(eastern, pacific);
Console.WriteLine(pacificTime.ToString("f")); // Friday, March 15, 2024 6:00 AM

// Use "o" for reliable round-trip serialization
string serialized   = DateTimeOffset.UtcNow.ToString("o");
DateTimeOffset back = DateTimeOffset.Parse(serialized, CultureInfo.InvariantCulture);

DateOnly and TimeOnly (C# 10+)

When you only need the date or time portion, DateOnly and TimeOnly express intent clearly and avoid accidental time/date operations.

C# Example Code
// DateOnly — date with no time component
DateOnly today    = DateOnly.FromDateTime(DateTime.Now);
DateOnly birthday = new DateOnly(1990, 6, 15);

Console.WriteLine(today.ToString("yyyy-MM-dd"));       // 2024-03-15
Console.WriteLine(birthday.ToString("MMMM d, yyyy"));  // June 15, 1990

int age = today.Year - birthday.Year;
if (today < birthday.AddYears(age)) age--;
Console.WriteLine($"Age: {age}");

// TimeOnly — time of day with no date component
TimeOnly openAt  = new TimeOnly(9, 0);
TimeOnly closeAt = new TimeOnly(17, 30);
TimeOnly now     = TimeOnly.FromDateTime(DateTime.Now);

Console.WriteLine(openAt.ToString("HH:mm"));    // 09:00
Console.WriteLine(closeAt.ToString("h:mm tt")); // 5:30 PM

bool isOpen = now >= openAt && now <= closeAt;
Console.WriteLine($"Store is open: {isOpen}");

// ParseExact works identically
DateOnly d = DateOnly.ParseExact("15/03/2024", "dd/MM/yyyy");
TimeOnly t = TimeOnly.ParseExact("14:30", "HH:mm");

Take It Further

C# 12 and .NET 8 book cover

The most comprehensive book covering C# 12 and .NET 8 from scratch to production.

C# 12 and .NET 8 — Modern Cross-Platform Development · Mark J. Price

Get it on Amazon →

As an Amazon Associate I earn from qualifying purchases.