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
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 PMUse 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.
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
mmis minutes, whileMMis the month number.hhis 12-hour time, whileHHis 24-hour time.- Use
yyyy-MM-ddoryyyyMMddfor filenames to avoid slashes and locale issues.
Standard Format Specifiers Reference
| Specifier | Description | Example (2024-03-15 14:30:45, en-US) |
|---|---|---|
d | Short date | 3/15/2024 |
D | Long date | Friday, March 15, 2024 |
t | Short time | 2:30 PM |
T | Long time | 2:30:45 PM |
f | Full date/time, short time | Friday, March 15, 2024 2:30 PM |
F | Full date/time, long time | Friday, March 15, 2024 2:30:45 PM |
g | General, short time | 3/15/2024 2:30 PM |
G | General, long time | 3/15/2024 2:30:45 PM |
M / m | Month and day | March 15 |
Y / y | Year and month | March 2024 |
s | Sortable, no timezone | 2024-03-15T14:30:45 |
O / o | Round-trip ISO 8601 | 2024-03-15T14:30:45.0000000 |
R / r | RFC 1123 | Fri, 15 Mar 2024 14:30:45 GMT |
u | Universal sortable | 2024-03-15 14:30:45Z |
Custom Format Specifiers Reference
| Specifier | Meaning | Example |
|---|---|---|
d / dd | Day, no/with leading zero | 5 / 05 |
ddd / dddd | Abbreviated / full day name | Fri / Friday |
M / MM | Month number, no/with leading zero | 3 / 03 |
MMM / MMMM | Abbreviated / full month name | Mar / March |
yy / yyyy | 2-digit / 4-digit year | 24 / 2024 |
h / hh | 12-hour clock, no/with leading zero | 2 / 02 |
H / HH | 24-hour clock, no/with leading zero | 14 / 14 |
m / mm | Minutes, no/with leading zero | 5 / 05 |
s / ss | Seconds, no/with leading zero | 9 / 09 |
fff | Milliseconds (3 digits) | 045 |
tt | AM/PM designator | PM |
zzz | UTC offset | +01:00 |
'text' | Literal text in single quotes | at, on, … |
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 15ParseExact 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.
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, 2024Culture-Specific Formatting
Output differs by culture. Use CultureInfo.InvariantCulture for storage and logs; use the user's locale for display.
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.0000000DateTimeOffset — Timezone-Aware Dates
Use DateTimeOffset instead of DateTime when your app spans multiple timezones. It stores the UTC offset alongside the value.
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.
// 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

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.