para net formato fecha convertir cambiar c# datetime datetime-format iso8601

c# - net - Dado un objeto DateTime, ¿cómo obtengo una fecha ISO 8601 en formato de cadena?



iso 8601 date format c# (15)

Dado:

DateTime.UtcNow

¿Cómo obtengo una cadena que representa el mismo valor en un formato compatible con ISO 8601 ?

Tenga en cuenta que ISO 8601 define una serie de formatos similares. El formato específico que estoy buscando es:

yyyy-MM-ddTHH:mm:ssZ


El especificador de formato estándar "s" representa una cadena de formato de fecha y hora personalizada definida por la propiedad DateTimeFormatInfo.SortableDateTimePattern . El patrón refleja un estándar definido ( ISO 8601 ), y la propiedad es de solo lectura. Por lo tanto, siempre es el mismo, independientemente de la cultura utilizada o del proveedor de formato proporcionado. La cadena de formato personalizado es "yyyy''-''MM''-''dd''T''HH'':''mm'':''ss" .

Cuando se utiliza este especificador de formato estándar, la operación de formato o análisis siempre utiliza la cultura invariable.

- desde MSDN


Es interesante que el formato personalizado "aaaa-MM-ddTHH: mm: ssK" (sin ms) sea el método de formato más rápido.

También es interesante que el formato "S" sea lento en Classic y rápido en Core ...

Por supuesto, los números son muy cercanos, entre algunas filas la diferencia es insignificante (las pruebas con el sufijo _Verify son las mismas que las que no tienen ese sufijo, demuestra la repetibilidad de los resultados)

BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393 Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4 Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC [Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0 Clr : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0 Core : .NET Core 4.6.25009.03, 64bit RyuJIT Method | Job | Runtime | Mean | Error | StdDev | Median | Min | Max | Rank | Gen 0 | Allocated | --------------------- |----- |-------- |-----------:|----------:|----------:|-----------:|-----------:|-----------:|-----:|-------:|----------:| CustomDev1 | Clr | Clr | 1,089.0 ns | 22.179 ns | 20.746 ns | 1,079.9 ns | 1,068.9 ns | 1,133.2 ns | 8 | 0.1086 | 424 B | CustomDev2 | Clr | Clr | 1,032.3 ns | 19.897 ns | 21.289 ns | 1,024.7 ns | 1,000.3 ns | 1,072.0 ns | 7 | 0.1165 | 424 B | CustomDev2WithMS | Clr | Clr | 1,168.2 ns | 16.543 ns | 15.474 ns | 1,168.5 ns | 1,149.3 ns | 1,189.2 ns | 10 | 0.1625 | 592 B | FormatO | Clr | Clr | 1,563.7 ns | 31.244 ns | 54.721 ns | 1,532.5 ns | 1,497.8 ns | 1,703.5 ns | 14 | 0.2897 | 976 B | FormatS | Clr | Clr | 1,243.5 ns | 24.615 ns | 31.130 ns | 1,229.3 ns | 1,200.6 ns | 1,324.2 ns | 13 | 0.2865 | 984 B | FormatS_Verify | Clr | Clr | 1,217.6 ns | 11.486 ns | 10.744 ns | 1,216.2 ns | 1,205.5 ns | 1,244.3 ns | 12 | 0.2885 | 984 B | CustomFormatK | Clr | Clr | 912.2 ns | 17.915 ns | 18.398 ns | 916.6 ns | 878.3 ns | 934.1 ns | 4 | 0.0629 | 240 B | CustomFormatK_Verify | Clr | Clr | 894.0 ns | 3.877 ns | 3.626 ns | 893.8 ns | 885.1 ns | 900.0 ns | 3 | 0.0636 | 240 B | CustomDev1 | Core | Core | 989.1 ns | 12.550 ns | 11.739 ns | 983.8 ns | 976.8 ns | 1,015.5 ns | 6 | 0.1101 | 423 B | CustomDev2 | Core | Core | 964.3 ns | 18.826 ns | 23.809 ns | 954.1 ns | 935.5 ns | 1,015.6 ns | 5 | 0.1267 | 423 B | CustomDev2WithMS | Core | Core | 1,136.0 ns | 21.914 ns | 27.714 ns | 1,138.1 ns | 1,099.9 ns | 1,200.2 ns | 9 | 0.1752 | 590 B | FormatO | Core | Core | 1,201.5 ns | 16.262 ns | 15.211 ns | 1,202.3 ns | 1,178.2 ns | 1,225.5 ns | 11 | 0.0656 | 271 B | FormatS | Core | Core | 993.5 ns | 19.272 ns | 24.372 ns | 999.4 ns | 954.2 ns | 1,029.5 ns | 6 | 0.0633 | 279 B | FormatS_Verify | Core | Core | 1,003.1 ns | 17.577 ns | 16.442 ns | 1,009.2 ns | 976.1 ns | 1,024.3 ns | 6 | 0.0674 | 279 B | CustomFormatK | Core | Core | 878.2 ns | 17.017 ns | 20.898 ns | 877.7 ns | 851.4 ns | 928.1 ns | 2 | 0.0555 | 215 B | CustomFormatK_Verify | Core | Core | 863.6 ns | 3.968 ns | 3.712 ns | 863.0 ns | 858.6 ns | 870.8 ns | 1 | 0.0550 | 215 B |

Código:

public class BenchmarkDateTimeFormat { public static DateTime dateTime = DateTime.Now; [Benchmark] public string CustomDev1() { var d = dateTime.ToUniversalTime(); var sb = new StringBuilder(20); sb.Append(d.Year).Append("-"); if (d.Month <= 9) sb.Append("0"); sb.Append(d.Month).Append("-"); if (d.Day <= 9) sb.Append("0"); sb.Append(d.Day).Append("T"); if (d.Hour <= 9) sb.Append("0"); sb.Append(d.Hour).Append(":"); if (d.Minute <= 9) sb.Append("0"); sb.Append(d.Minute).Append(":"); if (d.Second <= 9) sb.Append("0"); sb.Append(d.Second).Append("Z"); var text = sb.ToString(); return text; } [Benchmark] public string CustomDev2() { var u = dateTime.ToUniversalTime(); var sb = new StringBuilder(20); var y = u.Year; var d = u.Day; var M = u.Month; var h = u.Hour; var m = u.Minute; var s = u.Second; sb.Append(y).Append("-"); if (M <= 9) sb.Append("0"); sb.Append(M).Append("-"); if (d <= 9) sb.Append("0"); sb.Append(d).Append("T"); if (h <= 9) sb.Append("0"); sb.Append(h).Append(":"); if (m <= 9) sb.Append("0"); sb.Append(m).Append(":"); if (s <= 9) sb.Append("0"); sb.Append(s).Append("Z"); var text = sb.ToString(); return text; } [Benchmark] public string CustomDev2WithMS() { var u = dateTime.ToUniversalTime(); var sb = new StringBuilder(23); var y = u.Year; var d = u.Day; var M = u.Month; var h = u.Hour; var m = u.Minute; var s = u.Second; var ms = u.Millisecond; sb.Append(y).Append("-"); if (M <= 9) sb.Append("0"); sb.Append(M).Append("-"); if (d <= 9) sb.Append("0"); sb.Append(d).Append("T"); if (h <= 9) sb.Append("0"); sb.Append(h).Append(":"); if (m <= 9) sb.Append("0"); sb.Append(m).Append(":"); if (s <= 9) sb.Append("0"); sb.Append(s).Append("."); sb.Append(ms).Append("Z"); var text = sb.ToString(); return text; } [Benchmark] public string FormatO() { var text = dateTime.ToUniversalTime().ToString("o"); return text; } [Benchmark] public string FormatS() { var text = string.Concat(dateTime.ToUniversalTime().ToString("s"),"Z"); return text; } [Benchmark] public string FormatS_Verify() { var text = string.Concat(dateTime.ToUniversalTime().ToString("s"), "Z"); return text; } [Benchmark] public string CustomFormatK() { var text = dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK"); return text; } [Benchmark] public string CustomFormatK_Verify() { var text = dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK"); return text; } }

https://github.com/dotnet/BenchmarkDotNet se utilizó


La mayoría de estas respuestas tienen milisegundos / microsegundos que claramente no son compatibles con ISO 8601. La respuesta correcta sería:

System.DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssK"); // or System.DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");

Referencias:


Para convertir DateTime.UtcNow en una representación de cadena de yyyy-MM-ddTHH: mm: ssZ , puede usar el método ToString () de la estructura de DateTime con una cadena de formato personalizada. Cuando utilice cadenas de formato personalizado con un DateTime, es importante recordar que debe escapar de sus separadores utilizando comillas simples.

Lo siguiente devolverá la representación de cadena que deseaba:

DateTime.UtcNow.ToString("yyyy''-''MM''-''dd''T''HH'':''mm'':''ss''Z''", DateTimeFormatInfo.InvariantInfo)


Para formatear como 2018-06-22T13: 04: 16 que se puede pasar en el URI de un uso de API:

public static string FormatDateTime(DateTime dateTime) { return dateTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture); }


Puede obtener la "Z" ( ISO 8601 UTC ) con el siguiente código:

Dim tmpDate As DateTime = New DateTime(Now.Ticks, DateTimeKind.Utc) Dim res as String = tmpDate.toString("o") ''2009-06-15T13:45:30.0000000Z


Aquí es por qué:

La ISO 8601 tiene algunos formatos diferentes:

DateTimeKind.Local

2009-06-15T13:45:30.0000000-07:00

DateTimeKind.Utc

2009-06-15T13:45:30.0000000Z

DateTimeKind.Unspecified

2009-06-15T13:45:30.0000000


.NET nos proporciona una enumeración con esas opciones:

''2009-06-15T13:45:30.0000000-07:00 Dim strTmp1 As String = New DateTime(Now.Ticks, DateTimeKind.Local).ToString("o") ''2009-06-15T13:45:30.0000000Z Dim strTmp2 As String = New DateTime(Now.Ticks, DateTimeKind.Utc).ToString("o") ''2009-06-15T13:45:30.0000000 Dim strTmp3 As String = New DateTime(Now.Ticks, DateTimeKind.Unspecified).ToString("o")

Nota : si aplica la "utilidad de observación" de Visual Studio 2008 a la parte toString ("o") puede obtener resultados diferentes, no sé si es un error, pero en este caso tiene mejores resultados utilizando una variable String si estas depurando

Fuente: Cadenas de formato de fecha y hora estándar (MSDN)


Si debe usar DateTime según ISO 8601, entonces ToString ("o") debe proporcionar lo que está buscando. Por ejemplo,

2015-07-06T12:08:27

Sin embargo, DateTime + TimeZone puede presentar otros problemas como se describe en la publicación del blog DateTime y DateTimeOffset en .NET: buenas prácticas y dificultades comunes

DateTime tiene innumerables trampas que están diseñadas para dar errores a tu código:

1.- Los valores de DateTime con DateTimeKind.Unspecified son malas noticias.

2.- DateTime no se preocupa por UTC / Local cuando hace comparaciones.

3.- Los valores de DateTime no son conscientes de las cadenas de formato estándar.

4.- El análisis de una cadena que tiene un marcador UTC con DateTime no garantiza una hora UTC.


Si está desarrollando bajo SharePoint 2010 o superior, puede usar

using Microsoft.SharePoint; using Microsoft.SharePoint.Utilities; ... string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)


Utilizar:

private void TimeFormats() { DateTime localTime = DateTime.Now; DateTime utcTime = DateTime.UtcNow; DateTimeOffset localTimeAndOffset = new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime)); //UTC string strUtcTime_o = utcTime.ToString("o"); string strUtcTime_s = utcTime.ToString("s"); string strUtcTime_custom = utcTime.ToString("yyyy-MM-ddTHH:mm:ssK"); //Local string strLocalTimeAndOffset_o = localTimeAndOffset.ToString("o"); string strLocalTimeAndOffset_s = localTimeAndOffset.ToString("s"); string strLocalTimeAndOffset_custom = utcTime.ToString("yyyy-MM-ddTHH:mm:ssK"); //Output Response.Write("<br/>UTC<br/>"); Response.Write("strUtcTime_o: " + strUtcTime_o + "<br/>"); Response.Write("strUtcTime_s: " + strUtcTime_s + "<br/>"); Response.Write("strUtcTime_custom: " + strUtcTime_custom + "<br/>"); Response.Write("<br/>Local Time<br/>"); Response.Write("strLocalTimeAndOffset_o: " + strLocalTimeAndOffset_o + "<br/>"); Response.Write("strLocalTimeAndOffset_s: " + strLocalTimeAndOffset_s + "<br/>"); Response.Write("strLocalTimeAndOffset_custom: " + strLocalTimeAndOffset_custom + "<br/>"); }

SALIDA

UTC strUtcTime_o: 2012-09-17T22:02:51.4021600Z strUtcTime_s: 2012-09-17T22:02:51 strUtcTime_custom: 2012-09-17T22:02:51Z Local Time strLocalTimeAndOffset_o: 2012-09-17T15:02:51.4021600-07:00 strLocalTimeAndOffset_s: 2012-09-17T15:02:51 strLocalTimeAndOffset_custom: 2012-09-17T22:02:51Z

Fuentes:


Yo solo usaría XmlConvert :

XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.RoundtripKind);

Se conservará automáticamente la zona horaria.


DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture) debe proporcionarle lo que está buscando, ya que el especificador de formato "s" se describe como un patrón de fecha / hora clasificable. Cumple con la norma ISO 8601.


DateTime.Now.ToString("yyyy-MM-dd''T''HH:mm:ss zzz"); DateTime.Now.ToString("O");

NOTA: Dependiendo de la conversión que esté realizando en su final, utilizará la primera línea (la que más le guste) o la segunda.

Asegúrese de aplicar el formato solo a la hora local, ya que "zzz" es la información de zona horaria para la conversión UTC.


DateTime.UtcNow.ToString("s")

Devuelve algo así como 2008-04-10T06: 30: 00

UtcNow obviamente devuelve una hora UTC por lo que no hay daño en:

string.Concat(DateTime.UtcNow.ToString("s"), "Z")


DateTime.UtcNow.ToString("yyyy-MM-ddTHH//:mm//:ss.fffffffzzz");

Esto te da una fecha similar a la del 2008-09-22T13: 57: 31.2311892-04: 00 .

Otra forma es:

DateTime.UtcNow.ToString("o");

que le da 2008-09-22T14: 01: 54.9571247Z

Para obtener el formato especificado, puede utilizar:

DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")

Opciones de formato de fecha y hora


System.DateTime.UtcNow.ToString("o")

=>

val it : string = "2013-10-13T13:03:50.2950037Z"