Dato un oggetto DateTime, come posso ottenere una data ISO 8601 in formato stringa?


790

Dato:

DateTime.UtcNow

Come ottengo una stringa che rappresenta lo stesso valore in un formato conforme a ISO 8601 ?

Si noti che ISO 8601 definisce una serie di formati simili. Il formato specifico che sto cercando è:

yyyy-MM-ddTHH:mm:ssZ

Risposte:


780

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")

DateTime Opzioni di formattazione


20
In questi giorni, farlo (cercando di rendere l'ora UTC con un offset, il che non ha molto senso) genera un'eccezione. Quindi, concordo con gli altri sul fatto che il formato "s" con la cultura invariante sia probabilmente più corretto. Cordiali saluti, il messaggio di formatexception è: "Un DateTime UTC viene convertito in testo in un formato che è corretto solo per l'ora locale. Ciò può accadere quando si chiama DateTime.ToString utilizzando l'identificatore di formato 'z', che includerà un offset del fuso orario locale nell'output ".
Tom Lianza,

9
Vivo in Australia, e per me ho dovuto usarlo ToString("yyyy-MM-ddTHH:mm:ssK")per funzionare (con il plugin jquery timeago che stavo usando).
GONeale,

6
Se si desidera includere la dt.ToString("s") + dt.ToString("zzz")differenza di fuso orario, procedere come segue: // 2013-12-05T07: 19: 04-08: 00
alekop

4
Le barre (\ :) causano problemi con la stringa ... inserisci un carattere @ per usare invece una stringa letterale.
Gigi,

6
@core: questo è uno dei formati standard, che è diverso dai formati personalizzati collegati: msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
Wayne

361

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.


34
Credo che questa sia la risposta corretta. Non ha senso definire esplicitamente yyyy-MM-etc se Microsoft ha già implementato ISO 8601. Anche la risposta di Iain era giusta, ma dovresti sempre specificare InvariantCulture (o qualsiasi altro CultureInfo) per molteplici ragioni (cioè non supporre mai che .NET dovrebbe supponiamo). Puoi anche usare: 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"
Jon Davis

20
Mentre è conforme, lascia fuori il fuso orario, in Zquesto modo: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36e non esiste una risoluzione di millisecondi che è molto bella da avere poiché i computer eseguono un discreto numero di tick al secondo.
Henrik,

9
Con ote ottieni 2012-06-26T11:55:36.1007668Zsignificati 36.1007668secondi, quindi ottieni la risoluzione fino a 1/10^7un 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 (.)
Henrik,


2
@binki - ora sono molto confuso. Secondo la documentazione che ho collegato in precedenza per SortableDateTimePattern , afferma che dovrebbe essere specifico per la cultura. TUTTAVIA, sembra essere contraddetto dai suoi stessi esempi (poiché sembrano tutti uguali); provare DateTime.Now.ToString("s", new CultureInfo(myCulture)).
drzaus,

87
DateTime.UtcNow.ToString("s")

Restituisce qualcosa di simile a 2008-04-10T06: 30: 00

UtcNowovviamente restituisce un orario UTC quindi non ci sono danni in:

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

11
Solo per interesse: perché string.Concat () anziché '+'?
Daniel Fortunov,

2
Abitudine, c'è una differenza?
Iain,

84
@KoenZomers: non penso sia corretto. Penso che a + bcompili 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.
Mark Byers,

78
Sì, Mark è corretto. Koen, sei appena caduto nella trappola di un'assurdamente prematura micro ottimizzazione, anche se hai ragione.
Noldorin,

7
@ greg84: Beh, non hai del tutto ragione. Guarda questo post dell'architetto Microsoft Rico Mariani: blogs.msdn.com/b/ricom/archive/2003/12/15/43628.aspx - dice che a + b si compila per concat + + ci sono alcune informazioni in più sull'uso corretto di StringBuilder.
mrówa,

37

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/>");

}

PRODUZIONE

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

fonti:


2
sembra che tu sia vittima di una copia in costume locale ;-) string strLocalTimeAndOffset_custom = localTimeAndOffset.ToString("yyyy-MM-ddTHH:mm:ssK");si tradurrebbe in:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
Holly

oè un formato ISO-8601.
Yousha Aleayoub il

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

=>

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

D'accordo, questo è l'unico modo per essere assolutamente sicuri di avere una data / ora inequivocabile in qualsiasi fuso orario
Matt Wilko

23

È 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)


20

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.


2
ISO8601 è usato in strava per uno. Tuttavia, utilizzare: StartTime.ToString ("yyyy-MM-ddTHH: mm: ssZ") anziché ToString ("o") che aggiunge millisecondi ecc.
peterincumbria,

2
Per me, "yyyy-MM-dd-THH: mm: ssZ" ha letteralmente emesso "Z" alla fine della mia stringa anziché un indicatore di fuso orario, che non ha fatto quello che volevo. ToString ("o") in realtà ha fatto quello che mi serviva, molto più facile e più breve.
Blair Connolly,

18

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 *****

1
La risposta accettata di "o" funziona, ma dà una fastidiosa precisione (geez .XXXXXXX secondi) mentre preferisco questo poiché si ferma a pochi secondi.
jhocking

Anche quel documento afferma che "u" è ISO 8601, ma cosa c'è nello spazio invece di T? metterlo insieme microsoft
jhocking

@jhocking en.wikipedia.org/wiki/ISO_8601#cite_note-30 ISO 8601 è relativamente permissivo se lo leggi ...
rburte

16

Vorrei solo usare XmlConvert:

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

Conserverà automaticamente il fuso orario.


Sono andato avanti e ho aggiunto un metodo di estensione. public static class DateTimeExtensions {stringa statica pubblica ToIsoFormat (this DateTime dateTime) {return XmlConvert.ToString (dateTime, XmlDateTimeSerializationMode.RoundtripKind); }}
muruge

14

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:


15
Leggi il tuo link Wikipedia sotto "Times". Indica "Frazioni decimali", il che significa che ISO 8601 supporta sia i millisecondi che i microsecondi (ma le parti comunicanti possono limitare il numero di cifre decimali accettate).
Søren Boisen,

11
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.

Immagine


Non sono così sicuro #ChrisHynes poiché mi sta chiedendo del suggerimento che ho fatto riguardo alla prima riga di codice, ma se hai ragione, la risposta è "ReSharper"
PSM,

9

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


1
Quindi va bene usare .ToString("s")?
AhmetB - Google,

Credo di sì. - Finché il tuo requisito corrisponde alla domanda originale che è .. Ma dai un'occhiata all'avvertimento di Simon Wilson in basso
Amal

9

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)

9

È 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 _Verifysono 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



2

Se stai sviluppando in SharePoint 2010 o versioni successive puoi utilizzare

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

20
SharePoint, quando il tuo .Net non è abbastanza Java.
Henrik,

18
Usare SharePoint per questo è un po 'come portare una vasca di gelatina, una scatola bagnata di fiammiferi e 2 scimpanzé che camminano sul trapezio in una lotta armata.
nathanchere,

Anche in SharePoint si spera è possibile utilizzare il BCL del .ToString("o")o, meglio, $"My complicated string {dt:o}".
binki,

2

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);
}

1
Penso che questa stringa di date ISO sia invariante di cultura per definizione.
Jonas,

1

Come menzionato in altre risposte, DateTimeha problemi di progettazione.

NodaTime

Suggerisco di usare NodaTime per gestire i valori di data / ora:

  • Ora locale, data, datetime
  • Tempo globale
  • Tempo con fuso orario
  • Periodo
  • Durata

Formattazione

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 NodaTimecodice sembra abbastanza dettagliato. Ma i tipi sono davvero utili. Aiutano a gestire correttamente i valori di data / ora.

Newtonsoft.Json

Per utilizzare NodaTimecon Newtonsoft.Jsonè necessario aggiungere riferimento al NodaTime.Serialization.JsonNetpacchetto NuGet e le opzioni di configurazione JSON.

services
    .AddMvc()
    .AddJsonOptions(options =>
    {
        var settings=options.SerializerSettings;
        settings.DateParseHandling = DateParseHandling.None;
        settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.