Respuestas:
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")
ToString("yyyy-MM-ddTHH:mm:ssK")
para que esto funcionara (con el complemento jquery timeago que estaba usando).
dt.ToString("s") + dt.ToString("zzz")
// 2013-12-05T07: 19: 04-08: 00
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.
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"
Z
con este aspecto: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36
y no hay una resolución de milisegundos que sea muy buena, ya que las computadoras hacen una buena cantidad de tics por segundo.
o
eso obtienes segundos de 2012-06-26T11:55:36.1007668Z
significado 36.1007668
, por lo que obtienes una resolución de hasta 1/10^7
un 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 (.)
"s"
no tiene sentido porque: "" O "(u" o ")," R "(o" r ")," s "y" u ". Estas cadenas corresponden a cadenas de formato personalizado definidas por la cultura invariante. Producen representaciones en cadena de valores de fecha y hora que están destinados a ser idénticos en todas las culturas ".
DateTime.Now.ToString("s", new CultureInfo(myCulture))
.
DateTime.UtcNow.ToString("s")
Devuelve algo como 2008-04-10T06: 30: 00
UtcNow
obviamente devuelve una hora UTC para que no haya daño en:
string.Concat(DateTime.UtcNow.ToString("s"), "Z")
a + b
compila 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.
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/>");
}
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
string strLocalTimeAndOffset_custom = localTimeAndOffset.ToString("yyyy-MM-ddTHH:mm:ssK");
resultaría en:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
o
es un formato ISO-8601.
System.DateTime.UtcNow.ToString("o")
=>
val it : string = "2013-10-13T13:03:50.2950037Z"
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)
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.
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 *****
Yo solo usaría XmlConvert
:
XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.RoundtripKind);
Conservará automáticamente la zona horaria.
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
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.
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
.ToString("s")
?
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)
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 _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 fue utilizado
Usando Newtonsoft.Json, puedes hacer
JsonConvert.SerializeObject(DateTime.UtcNow)
Ejemplo: https://dotnetfiddle.net/O2xFSl
Si está desarrollando en SharePoint 2010 o superior, puede usar
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
.ToString("o")
o, mejor, $"My complicated string {dt:o}"
.
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);
}
Como se mencionó en otra respuesta, DateTime
tiene problemas por diseño.
Sugiero usar NodaTime para administrar valores de fecha / hora:
Entonces, para crear y formatear ZonedDateTime
puede 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 NodaTime
código parece bastante detallado. Pero los tipos son realmente útiles. Ayudan a manejar los valores de fecha / hora correctamente.
Para utilizar
NodaTime
conNewtonsoft.Json
necesita añadir referencia aNodaTime.Serialization.JsonNet
paquete 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);
});