DateTime in ISO 8601 in C#: A Complete Guide with Answers to Common Questions

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How to Convert DateTime to an ISO 8601 String in C#? A Problem That Troubles Even Experienced Developers

\n\n

Have you ever encountered a situation where your API returns a date in the format "2023-01-15T10:30:00", but the client doesn't understand it? Or, conversely, you receive a date from an external service that looks like "2023-01-15T10:30:00+03:00", and your parser breaks? Sound familiar? If you work with C# and the DateTime object, the issue of obtaining an ISO 8601 string is a classic. This question has garnered thousands of views on Stack Overflow, and for good reason. Today, we will once and for all figure out how to correctly convert DateTime to an ISO 8601 format string, avoiding common pitfalls.

\n\n

We won't just show a couple of lines of code. We will break down the C# DateTime format for ISO 8601, examine working with time zones, milliseconds, and answer the most frequent questions. Let's go!

\n\n

What is ISO 8601 and Why is it Important?

\n\n

ISO 8601 is an international standard for representing dates and times. It looks like this: 2023-12-25T14:30:00.0000000+03:00. Key features:

\n
    \n
  • T separator between date and time.
  • \n
  • Time zone is indicated at the end (Z for UTC or an offset like +05:00).
  • \n
  • Fractional part of seconds (milliseconds, ticks).
  • \n
\n

Why is this necessary? JSON, XML, REST APIs, databases — everywhere you need an unambiguous transmission of a point in time, without being tied to the server's local culture. An incorrect format — and your parser on the other side might discard hours or confuse the day with the month. Therefore, the ISO 8601 date format in C# is a must-have skill for any backend developer.

\n\n

The Simplest Way: DateTime.ToString() with the "o" Format

\n\n

In C#, there is a built-in format specifier for the round-trip format — the letter "o" (lowercase). It provides a complete ISO 8601 string with maximum precision.

\n\n
DateTime now = DateTime.Now;\nstring isoString = now.ToString("o");\nConsole.WriteLine(isoString);\n// Example output: 2023-12-25T14:30:00.1234567+03:00
\n\n

This is the simplest way to get an ISO 8601 string in C#. But there is a nuance: if your DateTime has Kind = Unspecified, then the time zone will not be indicated at the end of the string. This can be a problem for strict parsers. The solution is to always use DateTimeOffset or explicitly set the Kind.

\n\n

How to Get ISO 8601 Without Milliseconds?

\n\n

Sometimes milliseconds (or even ticks) are not needed. For example, for logs or simple dates. Use a custom format:

\n\n
DateTime now = DateTime.UtcNow;\nstring isoShort = now.ToString("yyyy-MM-ddTHH:mm:ssK");\nConsole.WriteLine(isoShort);\n// Example: 2023-12-25T14:30:00Z
\n\n

Here, K is the time zone specifier. For UTC it gives Z, for local time it gives the offset.

\n\n

The Problem with Time Zones: DateTime vs DateTimeOffset

\n\n

The main pain point for developers is the confusion between DateTime and DateTimeOffset. If you want to get an ISO 8601 date in C# that will be unambiguously interpreted anywhere in the world, use DateTimeOffset. It always contains the offset from UTC.

\n\n
DateTimeOffset nowOffset = DateTimeOffset.Now;\nstring isoOffset = nowOffset.ToString("o");\nConsole.WriteLine(isoOffset);\n// Example: 2023-12-25T14:30:00.1234567+03:00
\n\n

If you are working with DateTime, always check its Kind property:

\n
    \n
  • DateTimeKind.Utc — gives Z at the end.
  • \n
  • DateTimeKind.Local — gives the local offset (e.g., +03:00).
  • \n
  • DateTimeKind.Unspecified — gives noth

Blogs

Book Recommendations