DateTime en ISO 8601 en C#: guía completa con respuestas a preguntas frecuentes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Cómo convertir DateTime a una cadena ISO 8601 en C#? El problema que atormenta incluso a los experimentados

\n\n

¿Alguna vez se ha encontrado con una situación en la que su API devuelve una fecha en el formato "2023-01-15T10:30:00" y el cliente no la entiende? ¿O, por el contrario, recibe una fecha de un servicio externo que se ve como "2023-01-15T10:30:00+03:00" y su analizador se rompe? ¿Le suena familiar? Si trabaja con C# y el objeto DateTime, el problema de obtener una cadena ISO 8601 es un clásico. En Stack Overflow, esta pregunta ha acumulado miles de visitas, y no es para menos. Hoy, de una vez por todas, entenderemos cómo convertir correctamente DateTime a una cadena en formato ISO 8601, evitando las trampas típicas.

\n\n

No solo mostraremos un par de líneas de código. Analizaremos el formato DateTime de C# para ISO 8601, veremos el trabajo con zonas horarias, milisegundos y responderemos las preguntas más frecuentes. ¡Allá vamos!

\n\n

¿Qué es ISO 8601 y por qué es importante?

\n\n

ISO 8601 es un estándar internacional para la representación de fecha y hora. Se ve así: 2023-12-25T14:30:00.0000000+03:00. Las características clave son:

\n
    \n
  • Separador T entre la fecha y la hora.
  • \n
  • Zona horaria indicada al final (Z para UTC o desplazamiento como +05:00).
  • \n
  • Parte fraccionaria de segundos (milisegundos, tics).
  • \n
\n

¿Para qué sirve esto? JSON, XML, API REST, bases de datos: en cualquier lugar donde se necesite una transmisión inequívoca de un momento en el tiempo, sin depender de la cultura local del servidor. Un formato incorrecto y su analizador del otro lado podría descartar las horas o confundir el día con el mes. Por lo tanto, el formato de fecha ISO 8601 en C# es una habilidad imprescindible para cualquier desarrollador backend.

\n\n

La forma más sencilla: DateTime.ToString() con el formato "o"

\n\n

En C# hay un especificador de formato incorporado para el formato de ida y vuelta (round-trip): es la letra "o" (minúscula). Proporciona una cadena ISO 8601 completa con la máxima precisión.

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

Esta es la forma más sencilla de obtener una cadena ISO 8601 en C#. Pero hay un matiz: si su DateTime tiene Kind = Unspecified, al final de la cadena no habrá indicación de zona horaria. Esto puede ser un problema para analizadores estrictos. La solución es usar siempre DateTimeOffset o establecer explícitamente el Kind.

\n\n

¿Cómo obtener ISO 8601 sin milisegundos?

\n\n

A veces los milisegundos (o incluso los tics) no son necesarios. Por ejemplo, para registros o fechas simples. Use un formato personalizado:

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

Aquí K es el especificador de zona horaria. Para UTC da Z, para hora local da el desplazamiento.

\n\n

Problema con las zonas horarias: DateTime vs DateTimeOffset

\n\n

El principal dolor de cabeza de los desarrolladores es la confusión entre DateTime y DateTimeOffset. Si desea obtener una fecha ISO 8601 en C# que se interprete sin ambigüedad en cualquier parte del mundo, use DateTimeOffset. Siempre contiene el desplazamiento de UTC.

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

Si trabaja con DateTime, siempre verifique su propiedad Kind:

\n
    \n
  • DateTimeKind.Utc — da Z al final.
  • \n
  • DateTimeKind.Local — da el desplazamiento local (por ejemplo, +03:00).
  • \n
  • DateTimeKind.Unspecified — no da nada al final.
  • \n

Blogs

Book Recommendations