Wie erhalte ich bei einem DateTime-Objekt ein ISO 8601-Datum im Zeichenfolgenformat?


790

Gegeben:

DateTime.UtcNow

Wie erhalte ich eine Zeichenfolge, die in einem ISO 8601- kompatiblen Format denselben Wert darstellt ?

Beachten Sie, dass ISO 8601 eine Reihe ähnlicher Formate definiert. Das spezifische Format, das ich suche, ist:

yyyy-MM-ddTHH:mm:ssZ

Antworten:


780

Hinweis für die Leser: Mehrere Kommentatoren haben auf einige Probleme in dieser Antwort hingewiesen (insbesondere im Zusammenhang mit dem ersten Vorschlag). Weitere Informationen finden Sie im Kommentarbereich.

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

Dies gibt Ihnen ein Datum ähnlich dem 2008-09-22T13: 57: 31.2311892-04: 00 .

Ein anderer Weg ist:

DateTime.UtcNow.ToString("o");

Das gibt Ihnen 2008-09-22T14: 01: 54.9571247Z

Um das angegebene Format zu erhalten, können Sie Folgendes verwenden:

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

DateTime-Formatierungsoptionen


20
Heutzutage löst dies eine Ausnahme aus (der Versuch, eine UTC-Zeit mit einem Offset zu rendern, was wenig Sinn macht). Daher stimme ich den anderen zu, dass das "s" -Format mit der invarianten Kultur wahrscheinlich korrekter ist. Zu Ihrer Information lautet die Meldung der formatexception: "Eine UTC-DateTime wird in Text in einem Format konvertiert, das nur für Ortszeiten korrekt ist. Dies kann passieren, wenn DateTime.ToString mit dem Formatbezeichner 'z' aufgerufen wird, der einen lokalen Zeitzonenversatz enthält in der Ausgabe. "
Tom Lianza

9
Ich lebe in Australien und musste es für mich verwenden, ToString("yyyy-MM-ddTHH:mm:ssK")damit es funktioniert (mit dem von mir verwendeten jquery timeago-Plugin).
GONeale

6
Wenn Sie den Zeitzonenversatz einschließen möchten, tun Sie dies: dt.ToString("s") + dt.ToString("zzz")// 2013-12-05T07: 19: 04-08: 00
alekop

4
Die Schrägstriche (\ :) verursachen Probleme mit der Zeichenfolge ... Geben Sie ein @ -Zeichen ein, um stattdessen ein Zeichenfolgenliteral zu verwenden.
Gigi

6
@core: Dies ist eines der Standardformate, das sich von den verknüpften benutzerdefinierten Formaten unterscheidet: msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
Wayne

361

DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)sollte Ihnen das geben, wonach Sie suchen, da der Formatbezeichner "s" als sortierbares Datums- / Zeitmuster beschrieben wird; entspricht ISO 8601.


34
Ich glaube das ist die richtige Antwort. Es macht keinen Sinn, das JJJJ-MM-etc explizit zu definieren, wenn Microsoft bereits ISO 8601 implementiert hat. Iains Antwort war ebenfalls richtig, aber Sie sollten die InvariantCulture (oder eine andere CultureInfo) immer aus mehreren Gründen angeben (dh niemals annehmen, dass .NET dies sollte einfach annehmen). Sie können auch verwenden: DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.SortableDateTimePattern); Da alle diese die Zeitzone usw. ausschließen, haben Sie möglicherweise keine andere Wahl, als den expliziten Formatierer zu verwenden, dh"yyyy-MM-ddTHH:mm:ss.fffZ"
Jon Davis

20
Während es konform ist, lässt es die Zeitzone aus und Zsieht folgendermaßen aus: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36und es gibt keine Millisekundenauflösung, die sehr schön ist, da Computer eine angemessene Anzahl von Ticks pro Sekunde ausführen.
Henrik

9
Mit oihr erhalten 2012-06-26T11:55:36.1007668ZSinn 36.1007668Sekunden, also erhalten Sie Auflösung von bis zu 1/10^7einer Sekunde. Von 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 - jetzt bin ich sehr verwirrt. Laut der Dokumentation, die ich zuvor für SortableDateTimePattern verlinkt habe , heißt es, dass es kulturspezifisch sein sollte. Es scheint jedoch durch seine eigenen Beispiele widersprochen zu werden (da sie alle gleich aussehen); versuche es DateTime.Now.ToString("s", new CultureInfo(myCulture)).
Drzaus

87
DateTime.UtcNow.ToString("s")

Gibt so etwas wie 2008-04-10T06: 30: 00 zurück

UtcNowGibt offensichtlich eine UTC- Zeit zurück, sodass Folgendes nicht schadet:

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

11
Nur aus Interesse: Warum string.Concat () statt '+'?
Daniel Fortunov

2
Habbit, gibt es einen Unterschied?
Iain

84
@KoenZomers: Ich denke nicht, dass das richtig ist. Ich denke, es wird a + bmit demselben Zwischencode kompiliert wie string.Concat(a, b)(vorausgesetzt, a und b sind natürlich Zeichenfolgen), sodass es keinen Unterschied in der Leistung oder im Speicherverbrauch gibt.
Mark Byers

78
Ja, Mark ist richtig. Koen, du bist gerade in die Falle einer absurd vorzeitigen Mikrooptimierung geraten, selbst wenn du richtig bist.
Noldorin

7
@ Greg84: Nun, du hast nicht ganz recht. Schauen Sie sich diesen Beitrag des Microsoft-Architekten Rico Mariani an: blogs.msdn.com/b/ricom/archive/2003/12/15/43628.aspx - er sagt, a + b kompiliert zu concat + es gibt einige weitere Informationen zur richtigen Verwendung von StringBuilder.
Mrówa

37

Verwenden:

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

}

AUSGABE

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

Quellen:


2
Sie scheinen ein Opfer des Kopierens nach lokaler Sitte zu sein ;-) string strLocalTimeAndOffset_custom = localTimeAndOffset.ToString("yyyy-MM-ddTHH:mm:ssK");würde dazu führen:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
Holly

oist ein ISO-8601-Format.
Yousha Aleayoub

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

=>

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

Einverstanden ist dies der einzige Weg, um absolut sicher zu sein, dass Sie ein eindeutiges Datum / eine eindeutige Uhrzeit in jeder Zeitzone haben
Matt Wilko

23

Sie können das "Z" ( ISO 8601 UTC ) mit dem nächsten Code erhalten:

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


Hier ist warum:

Die ISO 8601 haben verschiedene Formate:

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 bietet uns eine Aufzählung mit folgenden Optionen:

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

Hinweis : Wenn Sie das Visual Studio 2008-Dienstprogramm "watch" auf den Teil toString ("o") anwenden, erhalten Sie möglicherweise unterschiedliche Ergebnisse. Ich weiß nicht, ob es sich um einen Fehler handelt, aber in diesem Fall erzielen Sie mit einer String-Variablen bessere Ergebnisse wenn Sie debuggen.

Quelle: Standard-Datums- und Uhrzeitformatzeichenfolgen (MSDN)


20

Wenn Sie DateTime nach ISO 8601 verwenden müssen, sollte ToString ("o") das liefern, wonach Sie suchen. Zum Beispiel,

2015-07-06T12:08:27

DateTime + TimeZone kann jedoch andere Probleme verursachen, wie im Blogbeitrag DateTime und DateTimeOffset in .NET beschrieben: Gute Praktiken und häufige Fallstricke :

DateTime enthält unzählige Fallen, die Ihre Codefehler verursachen sollen:

1.- DateTime-Werte mit DateTimeKind.Unspecified sind schlechte Nachrichten.

2.- DateTime kümmert sich bei Vergleichen nicht um UTC / Local.

3.- DateTime-Werte kennen keine Standardformatzeichenfolgen.

4.- Das Parsen einer Zeichenfolge mit einer UTC-Markierung mit DateTime garantiert keine UTC-Zeit.


2
ISO8601 wird in strava für einen verwendet. Verwenden Sie jedoch bitte: StartTime.ToString ("JJJJ-MM-TTTHH: MM: SSZ") anstelle von ToString ("O"), das Millisekunden usw. hinzufügt
Peterincumbria

2
Für mich gab "yyyy-MM-tt-THH: mm: ssZ" buchstäblich "Z" am Ende meiner Zeichenfolge anstelle einer Zeitzonenmarkierung aus, die nicht das tat, was ich wollte. ToString ("o") hat tatsächlich das getan, was ich brauchte, viel einfacher und kürzer.
Blair Connolly

18

Überrascht, dass niemand es vorgeschlagen hat:

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

Das UniversalSortableDateTimePattern bringt Sie fast bis zu dem, was Sie wollen (was eher eine RFC 3339- Darstellung ist).


Hinzugefügt: Ich habe mich entschieden, die beantworteten Benchmarks zu verwenden https://stackoverflow.com/a/43793679/653058 angegebenen zu vergleichen.

tl: dr; es ist am teuren Ende, aber immer noch etwas mehr als eine halbe Millisekunde auf meinem beschissenen alten Laptop :-)

Implementierung:

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

Ergebnisse:

// * 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
Die akzeptierte Antwort von "o" funktioniert zwar, gibt aber eine ärgerliche Genauigkeit (meine Güte .XXXXXXX Sekunden), während ich dies bevorzuge, da es bei Sekunden stoppt.
Schock

Auch dieses Dokument behauptet, "u" sei ISO 8601, aber was ist mit dem Leerzeichen anstelle von T?
Holen

@jhocking en.wikipedia.org/wiki/ISO_8601#cite_note-30 ISO 8601 ist relativ freizügig, wenn Sie es
durchlesen

16

Ich würde nur verwenden XmlConvert:

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

Die Zeitzone wird automatisch beibehalten.


Ich ging voran und fügte eine Erweiterungsmethode hinzu. öffentliche statische Klasse DateTimeExtensions {öffentliche statische Zeichenfolge ToIsoFormat (diese DateTime dateTime) {return XmlConvert.ToString (dateTime, XmlDateTimeSerializationMode.RoundtripKind); }}
Muruge

14

Die meisten dieser Antworten haben Millisekunden / Mikrosekunden, was von ISO 8601 eindeutig nicht unterstützt wird. Die richtige Antwort wäre:

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

Verweise:


15
Lesen Sie Ihren eigenen Wikipedia-Link unter "Times". Es werden "Dezimalbrüche" erwähnt, was bedeutet, dass ISO 8601 sowohl Millisekunden als auch Mikrosekunden unterstützt (kommunizierende Parteien können jedoch die Anzahl der akzeptierten Dezimalstellen begrenzen).
Søren Boisen

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

DateTime.Now.ToString("O");

HINWEIS: Abhängig von der Konvertierung, die Sie an Ihrem Ende durchführen, verwenden Sie die erste Zeile (am ähnlichsten) oder die zweite.

Stellen Sie sicher, dass das Format nur zur Ortszeit angewendet wird, da "zzz" die Zeitzoneninformationen für die UTC-Konvertierung sind.

Bild


Ich bin mir nicht so sicher, #ChrisHynes, da er nach dem Vorschlag fragt, den ich bezüglich der ersten Codezeile gemacht habe, aber wenn Sie richtig sind und dies der Fall ist, lautet die Antwort "ReSharper"
PSM

9

Der "s"Standardformatbezeichner repräsentiert eine benutzerdefinierte Datums- und Zeitformatzeichenfolge, die durch die DateTimeFormatInfo.SortableDateTimePattern- Eigenschaft definiert wird . Das Muster entspricht einem definierten Standard ( ISO 8601 ) und die Eigenschaft ist schreibgeschützt. Daher ist es immer gleich, unabhängig von der verwendeten Kultur oder dem bereitgestellten Formatanbieter. Die benutzerdefinierte Formatzeichenfolge lautet "yyyy'-'MM'-'dd'T'HH':'mm':'ss".

Wenn dieser Standardformatbezeichner verwendet wird, verwendet die Formatierungs- oder Analyseoperation immer die invariante Kultur.

- von MSDN


1
Also ist es okay zu benutzen .ToString("s")?
AhmetB - Google

Ich glaube schon. - Solange Ihre Anforderung mit der ursprünglichen Frage übereinstimmt. Aber werfen Sie einen Blick auf die Warnung von Simon Wilson unten
Amal

9

So konvertieren Sie DateTime.UtcNow in eine Zeichenfolgendarstellung von yyyy-MM-ddTHH: mm: ssZ , können Sie die ToString () -Methode der DateTime-Struktur mit einer benutzerdefinierten Formatierungszeichenfolge verwenden. Wenn Sie benutzerdefinierte Formatzeichenfolgen mit einer DateTime verwenden, ist es wichtig zu beachten, dass Sie Ihre Trennzeichen mit einfachen Anführungszeichen umgehen müssen.

Im Folgenden wird die gewünschte Zeichenfolgendarstellung zurückgegeben:

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

9

Es ist interessant, dass das benutzerdefinierte Format "JJJJ-MM-TTTHH: MM: SSK" (ohne ms) die schnellste Formatmethode ist.

Interessant ist auch, dass das "S" -Format bei Classic langsam und bei Core schnell ist ...

Natürlich sind die Zahlen sehr nahe beieinander, zwischen einigen Zeilen ist der Unterschied unbedeutend (Tests mit Suffix _Verifysind die gleichen wie diejenigen ohne dieses Suffix, zeigt die Wiederholbarkeit der Ergebnisse).

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 |

Code:

    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 wurde verwendet



2

Wenn Sie unter SharePoint 2010 oder höher entwickeln, können Sie verwenden

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

20
SharePoint, wenn Ihr .NET nicht Java genug ist.
Henrik

18
Die Verwendung von SharePoint ist so etwas wie das Mitbringen einer Wanne Gelee, einer feuchten Schachtel Streichhölzer und 2 Trapez-Schimpansen zu einem Schusswechsel.
Nathanchere

Selbst in SharePoint können Sie hoffentlich die BCLs .ToString("o")oder besser verwenden $"My complicated string {dt:o}".
Binki

2

Um das Format 2018-06-22T13: 04: 16 zu formatieren , das im URI einer API übergeben werden kann, verwenden Sie:

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

1
Ich denke, diese ISO-Datumszeichenfolge ist per Definition kulturinvariant.
Jonas

1

Wie in anderen Antworten erwähnt, DateTimegibt es Probleme mit dem Design.

NodaTime

Ich schlage vor, NodaTime zum Verwalten von Datums- / Zeitwerten zu verwenden:

  • Ortszeit, Datum, Uhrzeit
  • Globale Zeit
  • Zeit mit Zeitzone
  • Zeitraum
  • Dauer

Formatierung

Zum Erstellen und Formatieren können ZonedDateTimeSie also den folgenden Codeausschnitt verwenden:

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

Für mich NodaTimesieht Code ziemlich ausführlich aus. Aber Typen sind wirklich nützlich. Sie helfen dabei, Datums- / Zeitwerte korrekt zu behandeln.

Newtonsoft.Json

Zur Verwendung NodaTimemit Newtonsoft.JsonIhnen anhand hinzufügen müssen NodaTime.Serialization.JsonNetNuGet Paket und zu konfigurieren JSON - Optionen.

services
    .AddMvc()
    .AddJsonOptions(options =>
    {
        var settings=options.SerializerSettings;
        settings.DateParseHandling = DateParseHandling.None;
        settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    });
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.