Risposte:
Nota per i lettori: diversi commentatori hanno sottolineato alcuni problemi in questa risposta (in particolare relativi al primo suggerimento). Fare riferimento alla sezione commenti per ulteriori informazioni.
DateTime.UtcNow.ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");
Questo ti dà una data simile a 2008-09-22T13: 57: 31.2311892-04: 00 .
Un altro modo è:
DateTime.UtcNow.ToString("o");
che ti dà 2008-09-22T14: 01: 54.9571247Z
Per ottenere il formato specificato, è possibile utilizzare:
DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")
ToString("yyyy-MM-ddTHH:mm:ssK")
per funzionare (con il plugin jquery timeago che stavo usando).
dt.ToString("s") + dt.ToString("zzz")
differenza di fuso orario, procedere come segue: // 2013-12-05T07: 19: 04-08: 00
DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)
dovrebbe darti quello che stai cercando in quanto l'identificatore di formato "s" è descritto come un modello di data / ora ordinabile; conforme a ISO 8601.
DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.SortableDateTimePattern);
Tuttavia, poiché tutti questi escludono il fuso orario, ecc., Potresti non avere altra scelta che usare il formattatore esplicito, ad esempio"yyyy-MM-ddTHH:mm:ss.fffZ"
Z
questo modo: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36
e non esiste una risoluzione di millisecondi che è molto bella da avere poiché i computer eseguono un discreto numero di tick al secondo.
o
te ottieni 2012-06-26T11:55:36.1007668Z
significati 36.1007668
secondi, quindi ottieni la risoluzione fino a 1/10^7
un secondo. Da 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"
non ha senso perché: "" O "(o" o ")," R "(o" r ")," s "e" u ". Queste stringhe corrispondono alle stringhe di formato personalizzate definite dalla cultura invariante. Producono rappresentazioni di stringhe di valori di data e ora che devono essere identici tra le culture. "
DateTime.Now.ToString("s", new CultureInfo(myCulture))
.
DateTime.UtcNow.ToString("s")
Restituisce qualcosa di simile a 2008-04-10T06: 30: 00
UtcNow
ovviamente restituisce un orario UTC quindi non ci sono danni in:
string.Concat(DateTime.UtcNow.ToString("s"), "Z")
a + b
compili con lo stesso codice intermedio di string.Concat(a, b)
(supponendo che aeb siano stringhe, ovviamente), quindi non ci sono differenze nelle prestazioni o nel consumo di memoria.
Uso:
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");
si tradurrebbe in:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
o
è un formato ISO-8601.
System.DateTime.UtcNow.ToString("o")
=>
val it : string = "2013-10-13T13:03:50.2950037Z"
È possibile ottenere la "Z" ( ISO 8601 UTC ) con il codice seguente:
Dim tmpDate As DateTime = New DateTime(Now.Ticks, DateTimeKind.Utc)
Dim res as String = tmpDate.toString("o") '2009-06-15T13:45:30.0000000Z
Ecco perché:
ISO 8601 ha diversi formati:
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 ci fornisce un enum con quelle opzioni:
'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 : se si applica l'utilità di visualizzazione di Visual Studio 2008 a toString ("o") si potrebbero ottenere risultati diversi, non so se si tratta di un bug, ma in questo caso si ottengono risultati migliori usando una variabile String se stai eseguendo il debug.
Fonte: stringhe di formato di data e ora standard (MSDN)
Se devi usare DateTime secondo ISO 8601, allora ToString ("o") dovrebbe produrre ciò che stai cercando. Per esempio,
2015-07-06T12:08:27
Tuttavia, DateTime + TimeZone potrebbe presentare altri problemi, come descritto nel post del blog DateTime e DateTimeOffset in .NET: buone pratiche e insidie comuni :
DateTime contiene innumerevoli trap progettate per fornire ai tuoi bug del codice:
1.- I valori DateTime con DateTimeKind.Unspecified sono cattive notizie.
2.- DateTime non si preoccupa di UTC / Local durante i confronti.
3.- I valori di DateTime non sono a conoscenza delle stringhe di formato standard.
4.- L'analisi di una stringa che ha un marcatore UTC con DateTime non garantisce un'ora UTC.
Sorpreso che nessuno lo abbia suggerito:
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
L'UniversalSortableDateTimePattern si ottiene quasi tutto il modo per ciò che si vuole (che è più di un RFC 3339 rappresentazione).
Aggiunto: ho deciso di utilizzare i benchmark che erano in risposta https://stackoverflow.com/a/43793679/653058 per confrontare il rendimento .
tl: dr; è alla fine costoso ma ancora poco più di mezzo millisecondo sul mio vecchio laptop schifoso :-)
Implementazione:
[Benchmark]
public string ReplaceU()
{
var text = dateTime.ToUniversalTime().ToString("u").Replace(' ', 'T');
return text;
}
risultati:
// * 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 *****
Vorrei solo usare XmlConvert
:
XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.RoundtripKind);
Conserverà automaticamente il fuso orario.
La maggior parte di queste risposte ha millisecondi / microsecondi che chiaramente non è supportato da ISO 8601. La risposta corretta sarebbe:
System.DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssK");
// or
System.DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");
Riferimenti:
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss zzz");
DateTime.Now.ToString("O");
NOTA: a seconda della conversione che stai effettuando, utilizzerai la prima riga (la maggior parte piace) o la seconda.
Assicurati di applicare il formato solo all'ora locale, poiché "zzz" sono le informazioni sul fuso orario per la conversione UTC.
L'
"s"
identificatore di formato standard rappresenta una stringa di formato data e ora personalizzata definita dalla proprietà DateTimeFormatInfo.SortableDateTimePattern . Il modello riflette uno standard definito ( ISO 8601 ) e la proprietà è di sola lettura. Pertanto, è sempre lo stesso, indipendentemente dalla cultura utilizzata o dal provider del formato fornito. La stringa di formato personalizzata è"yyyy'-'MM'-'dd'T'HH':'mm':'ss"
.Quando viene utilizzato questo identificatore di formato standard, l'operazione di formattazione o analisi utilizza sempre la cultura invariante.
- da MSDN
.ToString("s")
?
Per convertire DateTime.UtcNow in una rappresentazione in formato stringa di yyyy-MM-ddTHH: mm: ssZ , è possibile utilizzare il metodo ToString () della struttura DateTime con una stringa di formattazione personalizzata. Quando si utilizzano stringhe di formato personalizzate con un DateTime, è importante ricordare che è necessario sfuggire ai separatori utilizzando virgolette singole.
Di seguito verrà restituita la rappresentazione della stringa desiderata:
DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", DateTimeFormatInfo.InvariantInfo)
È interessante notare che il formato personalizzato "yyyy-MM-ddTHH: mm: ssK" (senza ms) è il metodo di formattazione più rapido.
Inoltre è interessante che il formato "S" sia lento su Classic e veloce su Core ...
Naturalmente i numeri sono molto vicini, tra alcune righe la differenza è insignificante (i test con il suffisso _Verify
sono gli stessi di quelli che sono senza quel suffisso, dimostrano la ripetibilità dei risultati)
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 |
Codice:
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 è stato utilizzato
Usando Newtonsoft.Json, puoi farlo
JsonConvert.SerializeObject(DateTime.UtcNow)
Esempio: https://dotnetfiddle.net/O2xFSl
Se stai sviluppando in SharePoint 2010 o versioni successive puoi utilizzare
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
.ToString("o")
o, meglio, $"My complicated string {dt:o}"
.
Per formattare come 2018-06-22T13: 04: 16 che può essere passato nell'URI di un utilizzo dell'API:
public static string FormatDateTime(DateTime dateTime)
{
return dateTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
}
Come menzionato in altre risposte, DateTime
ha problemi di progettazione.
Suggerisco di usare NodaTime per gestire i valori di data / ora:
Quindi, per creare e formattare ZonedDateTime
è possibile utilizzare il seguente frammento di codice:
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
Per me il NodaTime
codice sembra abbastanza dettagliato. Ma i tipi sono davvero utili. Aiutano a gestire correttamente i valori di data / ora.
Per utilizzare
NodaTime
conNewtonsoft.Json
è necessario aggiungere riferimento alNodaTime.Serialization.JsonNet
pacchetto NuGet e le opzioni di configurazione JSON.
services
.AddMvc()
.AddJsonOptions(options =>
{
var settings=options.SerializerSettings;
settings.DateParseHandling = DateParseHandling.None;
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
});