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

790

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
Iain
fuente

Respuestas:

780

Nota para los lectores: Varios comentaristas han señalado algunos problemas en esta respuesta (particularmente relacionados con la primera sugerencia). Consulte la sección de comentarios para obtener más información.

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

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

Otra forma es:

DateTime.UtcNow.ToString("o");

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

Para obtener el formato especificado, puede usar:

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

Opciones de formato de fecha y hora

Wayne
fuente
20
En estos días, hacer eso (tratar de representar una hora UTC con un desplazamiento, que no tiene mucho sentido) arroja una excepción. Entonces, estoy de acuerdo con los demás en que el formato "s" con la cultura invariante es probablemente más correcto. Para su información, el mensaje de formatexception es: "Un UTC DateTime se está convirtiendo en texto en un formato que solo es correcto para las horas locales. Esto puede suceder al llamar a DateTime.ToString utilizando el especificador de formato 'z', que incluirá un desplazamiento de zona horaria local en la salida ".
Tom Lianza
99
Vivo en Australia, y para mí tuve que usar ToString("yyyy-MM-ddTHH:mm:ssK")para que esto funcionara (con el complemento jquery timeago que estaba usando).
GONeale
66
Si desea incluir el desplazamiento de la zona horaria, haga esto: dt.ToString("s") + dt.ToString("zzz")// 2013-12-05T07: 19: 04-08: 00
alekop
44
Las barras diagonales (\ :) causan problemas con la cadena ... coloque un carácter @ para usar un literal de cadena en su lugar.
Gigi
66
@core: ese es uno de los formatos estándar, que es diferente de los formatos personalizados vinculados: msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
Wayne
361

DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)debería darle lo que está buscando ya que el especificador de formato "s" se describe como un patrón de fecha / hora ordenable; cumple con ISO 8601.

Simon Wilson
fuente
34
Creo que esta es la respuesta correcta. No tiene sentido definir explícitamente aaaa-MM-etc. si Microsoft ya implementó ISO 8601. La respuesta de Iain también fue correcta, pero siempre debe especificar InvariantCulture (o cualquier otra CultureInfo) por múltiples razones (es decir, nunca asuma que .NET debería solo asume). También puede usar: DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.SortableDateTimePattern); Sin embargo, dado que todo esto excluye la zona horaria, etc., es posible que no tenga más remedio que usar el formateador explícito, es decir"yyyy-MM-ddTHH:mm:ss.fffZ"
Jon Davis
20
Si bien se ajusta, deja de lado la zona horaria, Zcon este aspecto: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36y no hay una resolución de milisegundos que sea muy buena, ya que las computadoras hacen una buena cantidad de tics por segundo.
Henrik
99
Con oeso obtienes segundos de 2012-06-26T11:55:36.1007668Zsignificado 36.1007668, por lo que obtienes una resolución de hasta 1/10^7un segundo. De ISO8601: 2004If a decimal fraction is included, lower order time elements (if any) shall be omitted and the decimal fraction shall be divided from the integer part by the decimal sign [...] the comma (,) or full stop (.)
Henrik
2
@binki - ahora estoy muy confundido. De acuerdo con la documentación que vinculé anteriormente para SortableDateTimePattern , dice que debería ser específica de la cultura. SIN EMBARGO, parece estar en contradicción con sus propios ejemplos (ya que todos se ven iguales); tratar DateTime.Now.ToString("s", new CultureInfo(myCulture)).
drzaus
87
DateTime.UtcNow.ToString("s")

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

UtcNowobviamente devuelve una hora UTC para que no haya daño en:

string.Concat(DateTime.UtcNow.ToString("s"), "Z")
Iain
fuente
11
Solo por interés: ¿Por qué string.Concat () en lugar de '+'?
Daniel Fortunov
2
Habbit, ¿hay alguna diferencia?
Iain
84
@ KoenZomers: No creo que sea correcto. Creo que a + bcompila el mismo código intermedio que string.Concat(a, b)(suponiendo que ayb son cadenas, por supuesto), por lo que no hay diferencia en el rendimiento o el consumo de memoria.
Mark Byers
78
Sí, Mark está en lo correcto. Koen, acabas de caer en la trampa de una micro-optimización absurdamente prematura, incluso si tienes razón.
Noldorin
77
@ greg84: Bueno, no tienes toda la razón. Mire esta publicación del arquitecto de Microsoft Rico Mariani: blogs.msdn.com/b/ricom/archive/2003/12/15/43628.aspx : dice que a + b se compila para concat + hay más información sobre el uso adecuado de StringBuilder.
mrówa
37

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:

Don
fuente
2
parece que eres víctima de copiar en la costumbre local ;-) string strLocalTimeAndOffset_custom = localTimeAndOffset.ToString("yyyy-MM-ddTHH:mm:ssK");resultaría en:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
Holly
oes un formato ISO-8601.
Yousha Aleayoub
33
System.DateTime.UtcNow.ToString("o")

=>

val it : string = "2013-10-13T13:03:50.2950037Z"
Henrik
fuente
Estuvo de acuerdo en que esta es la única manera de estar absolutamente seguro de que tiene una fecha / hora inequívoca en cualquier zona horaria
Matt Wilko, del
23

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 toString ("o") , puede obtener resultados diferentes, no sé si es un error, pero en este caso tiene mejores resultados usando una variable String si estás depurando

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

Oaxas
fuente
20

Si debe usar DateTime para ISO 8601, entonces ToString ("o") debería producir 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 diseñadas para dar errores a su código:

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

2.- DateTime no se preocupa por UTC / Local al hacer comparaciones.

3.- Los valores de fecha y hora no son conscientes de las cadenas de formato estándar.

4.- Analizar una cadena que tiene un marcador UTC con DateTime no garantiza una hora UTC.

Alex Nolasco
fuente
2
ISO8601 se usa en strava para uno. Sin embargo, utilice: StartTime.ToString ("aaaa-MM-ddTHH: mm: ssZ") en lugar de ToString ("o") que agrega milisegundos, etc.
peterincumbria
2
Para mí, "aaaa-MM-dd-THH: mm: ssZ" literalmente generó "Z" al final de mi cadena en lugar de un marcador de zona horaria, que no hizo lo que quería. ToString ("o") realmente hizo lo que necesitaba, mucho más fácil y más corto.
Blair Connolly
18

Sorprendido de que nadie lo sugirió:

System.DateTime.UtcNow.ToString("u").Replace(' ','T')
# Using PowerShell Core to demo

# Lowercase "u" format
[System.DateTime]::UtcNow.ToString("u")
> 2020-02-06 01:00:32Z

# Lowercase "u" format with replacement
[System.DateTime]::UtcNow.ToString("u").Replace(' ','T')
> 2020-02-06T01:00:32Z

El UniversalSortableDateTimePattern le consigue casi todo el camino a lo que quiere (que es más bien un RFC 3339 la representación).


Agregado: decidí usar los puntos de referencia que estaban en la respuesta https://stackoverflow.com/a/43793679/653058 para comparar cómo funciona esto.

tl: dr; está en el extremo costoso, pero todavía un poco más de medio milisegundo en mi vieja computadora portátil :-)

Implementación:

[Benchmark]
public string ReplaceU()
{
   var text = dateTime.ToUniversalTime().ToString("u").Replace(' ', 'T');
   return text;
}

Resultados:

// * Summary *

BenchmarkDotNet=v0.11.5, OS=Windows 10.0.19002
Intel Xeon CPU E3-1245 v3 3.40GHz, 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.0.100
  [Host]     : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
  DefaultJob : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT


|               Method |     Mean |     Error |    StdDev |
|--------------------- |---------:|----------:|----------:|
|           CustomDev1 | 562.4 ns | 11.135 ns | 10.936 ns |
|           CustomDev2 | 525.3 ns |  3.322 ns |  3.107 ns |
|     CustomDev2WithMS | 609.9 ns |  9.427 ns |  8.356 ns |
|              FormatO | 356.6 ns |  6.008 ns |  5.620 ns |
|              FormatS | 589.3 ns |  7.012 ns |  6.216 ns |
|       FormatS_Verify | 599.8 ns | 12.054 ns | 11.275 ns |
|        CustomFormatK | 549.3 ns |  4.911 ns |  4.594 ns |
| CustomFormatK_Verify | 539.9 ns |  2.917 ns |  2.436 ns |
|             ReplaceU | 615.5 ns | 12.313 ns | 11.517 ns |

// * Hints *
Outliers
  BenchmarkDateTimeFormat.CustomDev2WithMS: Default     -> 1 outlier  was  removed (668.16 ns)
  BenchmarkDateTimeFormat.FormatS: Default              -> 1 outlier  was  removed (621.28 ns)
  BenchmarkDateTimeFormat.CustomFormatK: Default        -> 1 outlier  was  detected (542.55 ns)
  BenchmarkDateTimeFormat.CustomFormatK_Verify: Default -> 2 outliers were removed (557.07 ns, 560.95 ns)

// * Legends *
  Mean   : Arithmetic mean of all measurements
  Error  : Half of 99.9% confidence interval
  StdDev : Standard deviation of all measurements
  1 ns   : 1 Nanosecond (0.000000001 sec)

// ***** BenchmarkRunner: End *****
rburte
fuente
1
La respuesta aceptada de "o" funciona, pero da una cantidad molesta de precisión (geez .XXXXXXX segundos) mientras que prefiero esto ya que se detiene en segundos.
jhocking
Además, ese documento afirma que "u" es ISO 8601, pero ¿qué pasa con el espacio en lugar de T? juntarlo Microsoft
jhocking
@jhocking en.wikipedia.org/wiki/ISO_8601#cite_note-30 ISO 8601 es relativamente permisivo si lo lees ...
rburte
16

Yo solo usaría XmlConvert:

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

Conservará automáticamente la zona horaria.

Sumrak
fuente
Seguí adelante y agregué un método de extensión. public static class DateTimeExtensions {cadena estática pública ToIsoFormat (this DateTime dateTime) {return XmlConvert.ToString (dateTime, XmlDateTimeSerializationMode.RoundtripKind); }}
asesinar el
14

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

Justin Turner
fuente
15
Lea su propio enlace de Wikipedia en "Tiempos". Menciona "fracciones decimales", lo que significa que ISO 8601 admite milisegundos y microsegundos (pero las partes que se comunican pueden limitar el número de decimales aceptados).
Søren Boisen
11
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss zzz");

DateTime.Now.ToString("O");

NOTA: Dependiendo de la conversión que esté haciendo en su extremo, usará la primera línea (más parecida) 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.

imagen

PSM
fuente
No estoy tan seguro #ChrisHynes ya que está preguntando sobre la sugerencia que hice con respecto a la primera línea de código, pero si está en lo cierto y ese es el caso, la respuesta es "ReSharper"
PSM
9

El "s"especificador de formato estándar representa una cadena de formato de fecha y hora personalizada que se define mediante 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 suministrado. 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 formateo o análisis siempre utiliza la cultura invariante.

- de MSDN

Amal
fuente
1
¿Entonces está bien usarlo .ToString("s")?
AhmetB - Google
Eso creo. - Siempre y cuando su requisito coincida con la pregunta original que es .. Pero eche un vistazo a la advertencia de Simon Wilson a continuación
Amal
9

Para convertir DateTime.UtcNow en una representación de cadena de aaaa-MM-ddTHH: mm: ssZ , puede usar el método ToString () de la estructura DateTime con una cadena de formato personalizada. Al usar cadenas de formato personalizado con DateTime, es importante recordar que necesita escapar de sus separadores usando 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)
Opuesta
fuente
9

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 sufijo _Verifyson 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 fue utilizado

Roman Pokrovskij
fuente
3

Usando Newtonsoft.Json, puedes hacer

JsonConvert.SerializeObject(DateTime.UtcNow)

Ejemplo: https://dotnetfiddle.net/O2xFSl

blackforest-tom
fuente
1
La mejor respuesta aquí.
El integrador
2

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

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
Simon Logic
fuente
20
SharePoint, cuando su .Net no es lo suficientemente Java.
Henrik
18
Usar SharePoint para esto es algo así como llevar una tina de gelatina, una caja húmeda de fósforos y 2 chimpancés que caminan en trapecio a un tiroteo.
nathanchere
Incluso en SharePoint espero que usted puede utilizar el BCL de .ToString("o")o, mejor, $"My complicated string {dt:o}".
binki
2

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);
}
Nick Gallimore
fuente
1
Creo que esta cadena de fecha ISO es invariante de cultura por definición.
Jonas
1

Como se mencionó en otra respuesta, DateTimetiene problemas por diseño.

NodaTime

Sugiero usar NodaTime para administrar valores de fecha / hora:

  • Hora local, fecha, fecha y hora
  • Hora global
  • Hora con zona horaria
  • Período
  • Duración

Formateo

Entonces, para crear y formatear ZonedDateTimepuede usar el siguiente fragmento de código:

var instant1 = Instant.FromUtc(2020, 06, 29, 10, 15, 22);

var utcZonedDateTime = new ZonedDateTime(instant1, DateTimeZone.Utc);
utcZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
// 2020-06-29T10:15:22Z


var instant2 = Instant.FromDateTimeUtc(new DateTime(2020, 06, 29, 10, 15, 22, DateTimeKind.Utc));

var amsterdamZonedDateTime = new ZonedDateTime(instant2, DateTimeZoneProviders.Tzdb["Europe/Amsterdam"]);
amsterdamZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
// 2020-06-29T12:15:22Z

Para mí, el NodaTimecódigo parece bastante detallado. Pero los tipos son realmente útiles. Ayudan a manejar los valores de fecha / hora correctamente.

Newtonsoft.Json

Para utilizar NodaTimecon Newtonsoft.Jsonnecesita añadir referencia a NodaTime.Serialization.JsonNetpaquete NuGet y las opciones de configuración de JSON.

services
    .AddMvc()
    .AddJsonOptions(options =>
    {
        var settings=options.SerializerSettings;
        settings.DateParseHandling = DateParseHandling.None;
        settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    });
Vladimir Serykh
fuente