Étant donné un objet DateTime, comment puis-je obtenir une date ISO 8601 au format chaîne?

790

Donné:

DateTime.UtcNow

Comment puis-je obtenir une chaîne qui représente la même valeur dans un ISO 8601 format compatible ?

Notez que ISO 8601 définit un certain nombre de formats similaires. Le format spécifique que je recherche est:

yyyy-MM-ddTHH:mm:ssZ
Iain
la source

Réponses:

780

Note aux lecteurs: Plusieurs commentateurs ont signalé quelques problèmes dans cette réponse (liés notamment à la première suggestion). Reportez-vous à la section des commentaires pour plus d'informations.

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

Cela vous donne une date similaire à 2008-09-22T13: 57: 31.2311892-04: 00 .

Une autre façon est:

DateTime.UtcNow.ToString("o");

ce qui vous donne 2008-09-22T14: 01: 54.9571247Z

Pour obtenir le format spécifié, vous pouvez utiliser:

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

Options de formatage de DateTime

Wayne
la source
20
De nos jours, faire cela (essayer de rendre une heure UTC avec un décalage, ce qui n'a pas beaucoup de sens) lève une exception. Donc, je suis d'accord avec les autres que le format "s" avec la culture invariante est probablement plus correct. Pour info, le message du formatexception est: "Un UTC DateTime est converti en texte dans un format qui n'est correct que pour les heures locales. dans la sortie. "
Tom Lianza
9
J'habite en Australie, et pour moi j'ai dû l'utiliser ToString("yyyy-MM-ddTHH:mm:ssK")pour que cela fonctionne (avec le plugin jquery timeago que j'utilisais).
GONeale
6
Si vous souhaitez inclure le décalage du fuseau horaire, procédez comme dt.ToString("s") + dt.ToString("zzz")
suit
4
Les barres obliques (\ :) provoquent des problèmes avec la chaîne ... mettez un caractère @ pour utiliser un littéral de chaîne à la place.
Gigi
6
@core: c'est l'un des formats standard, qui est différent des formats personnalisés liés: msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
Wayne
361

DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)devrait vous donner ce que vous recherchez car le spécificateur de format "s" est décrit comme un modèle de date / heure triable; conforme à ISO 8601.

Simon Wilson
la source
34
Je pense que c'est la bonne réponse. Il est inutile de définir explicitement le yyyy-MM-etc si Microsoft a déjà implémenté ISO 8601. La réponse d'Iain était également correcte, mais vous devez toujours spécifier InvariantCulture (ou tout autre CultureInfo) pour plusieurs raisons (c'est-à-dire ne jamais supposer que .NET devrait supposez juste). Vous pouvez également utiliser: DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.SortableDateTimePattern); Cependant, étant donné que tous ces éléments excluent le fuseau horaire, etc., vous pourriez avoir d'autre choix que d'utiliser le formateur explicite, c'est"yyyy-MM-ddTHH:mm:ss.fffZ"
Jon Davis
20
Bien qu'il soit conforme, il laisse de côté le fuseau horaire, Zressemblant à ceci: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36et il n'y a pas de résolution en millisecondes qui est très agréable à avoir puisque les ordinateurs font un bon nombre de ticks par seconde.
Henrik
9
Avec ovous obtenez des secondes 2012-06-26T11:55:36.1007668Zsignificatives 36.1007668, vous obtenez donc une résolution jusqu'à 1/10^7une seconde. 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 - maintenant je suis très confus. Selon la documentation que j'ai liée plus tôt pour SortableDateTimePattern , il dit que cela devrait être spécifique à la culture. CEPENDANT, il semble être contredit par ses propres exemples (car ils se ressemblent tous); essayez DateTime.Now.ToString("s", new CultureInfo(myCulture)).
drzaus
88
DateTime.UtcNow.ToString("s")

Renvoie quelque chose comme 2008-04-10T06: 30: 00

UtcNowrenvoie évidemment une heure UTC donc il n'y a aucun mal à:

string.Concat(DateTime.UtcNow.ToString("s"), "Z")
Iain
la source
11
Juste par intérêt: pourquoi string.Concat () plutôt que '+'?
Daniel Fortunov
2
Habbit, y a-t-il une différence?
Iain
84
@KoenZomers: Je ne pense pas que ce soit correct. Je pense que a + bcompile dans le même code intermédiaire que string.Concat(a, b)(en supposant que a et b sont des chaînes, bien sûr) donc il n'y a pas de différence de performance ou de consommation de mémoire.
Mark Byers
78
Oui, Mark a raison. Koen, vous venez de tomber dans le piège d'une micro-optimisation absurdement prématurée, même si vous avez raison.
Noldorin
7
@ greg84: Eh bien, vous n'avez pas tout à fait raison. Regardez cet article de l'architecte Microsoft Rico Mariani: blogs.msdn.com/b/ricom/archive/2003/12/15/43628.aspx - il dit que a + b compile pour concat + il y a plus d'informations sur l'utilisation correcte de StringBuilder.
mrówa
37

Utilisation:

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

}

PRODUCTION

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

Sources:

Don
la source
2
semble que vous êtes victime de copier à la coutume locale ;-) string strLocalTimeAndOffset_custom = localTimeAndOffset.ToString("yyyy-MM-ddTHH:mm:ssK");entraînerait:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
Holly
oest un format ISO-8601.
Yousha Aleayoub
33
System.DateTime.UtcNow.ToString("o")

=>

val it : string = "2013-10-13T13:03:50.2950037Z"
Henrik
la source
D'accord, c'est la seule façon d'être absolument sûr que vous avez une date / heure sans ambiguïté sur n'importe quel fuseau horaire
Matt Wilko
23

Vous pouvez obtenir le "Z" ( ISO 8601 UTC ) avec le code suivant:

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


Voici pourquoi:

L'ISO 8601 a différents formats:

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 nous fournit une énumération avec ces options:

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

Remarque : Si vous appliquez l '"utilitaire de surveillance" de Visual Studio 2008 à la partie toString ("o"), vous pouvez obtenir des résultats différents, je ne sais pas si c'est un bogue, mais dans ce cas, vous obtenez de meilleurs résultats en utilisant une variable String si vous déboguez.

Source: chaînes de format de date et d'heure standard (MSDN)

Oaxas
la source
20

Si vous devez utiliser DateTime selon ISO 8601, alors ToString ("o") devrait fournir ce que vous recherchez. Par exemple,

2015-07-06T12:08:27

Cependant, DateTime + TimeZone peut présenter d'autres problèmes comme décrit dans le billet de blog DateTime et DateTimeOffset dans .NET: bonnes pratiques et pièges courants :

DateTime contient d'innombrables pièges qui sont conçus pour donner à vos bogues de code:

1.- Les valeurs DateTime avec DateTimeKind.Unspecified sont de mauvaises nouvelles.

2.- DateTime ne se soucie pas de UTC / Local lors des comparaisons.

3.- Les valeurs DateTime ne connaissent pas les chaînes de format standard.

4.- L'analyse d'une chaîne qui a un marqueur UTC avec DateTime ne garantit pas une heure UTC.

Alex Nolasco
la source
2
ISO8601 est utilisé dans strava pour un. Cependant, veuillez utiliser: StartTime.ToString ("yyyy-MM-ddTHH: mm: ssZ") plutôt que ToString ("o") qui ajoute des millisecondes, etc.
peterincumbria
2
Pour moi, "aaaa-MM-jj-THH: mm: ssZ" a littéralement sorti "Z" à la fin de ma chaîne au lieu d'un marqueur de fuseau horaire, ce qui n'a pas fait ce que je voulais. ToString ("o") a réellement fait ce dont j'avais besoin, beaucoup plus facile et plus court.
Blair Connolly
18

Surpris que personne ne l'ait suggéré:

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

Le UniversalSortableDateTimePattern vous obtient presque tout le chemin à ce que vous voulez (qui est plus une RFC 3339 représentation).


Ajouté: j'ai décidé d'utiliser les repères qui étaient dans la réponse https://stackoverflow.com/a/43793679/653058 pour comparer comment cela fonctionne.

tl: dr; c'est à la fin cher mais encore un peu plus d'une demi-milliseconde sur mon vieux portable merdique :-)

La mise en oeuvre:

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

Résultats:

// * 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
la source
1
La réponse acceptée de "o" fonctionne, mais elle donne une précision gênante (bonjour .XXXXXXX secondes) alors que je préfère cela car elle s'arrête à quelques secondes.
jhocking
De plus, ce document prétend que "u" est ISO 8601, mais qu'en est-il de l'espace au lieu de T? rassembler microsoft
jhocking
@jhocking en.wikipedia.org/wiki/ISO_8601#cite_note-30 ISO 8601 est relativement permissif si vous le lisez ...
rburte
16

Je voudrais simplement utiliser XmlConvert:

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

Il conservera automatiquement le fuseau horaire.

Sumrak
la source
Je suis allé de l'avant et j'ai ajouté une méthode d'extension. classe statique publique DateTimeExtensions {chaîne statique publique ToIsoFormat (this DateTime dateTime) {return XmlConvert.ToString (dateTime, XmlDateTimeSerializationMode.RoundtripKind); }}
muruge
14

La plupart de ces réponses ont des millisecondes / microsecondes, ce qui n'est clairement pas pris en charge par ISO 8601. La bonne réponse serait:

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

Références:

Justin Turner
la source
15
Lisez votre propre lien Wikipedia sous "Times". Il mentionne les "fractions décimales", ce qui signifie que l'ISO 8601 prend en charge à la fois les millisecondes et les microsecondes (mais les parties communicantes peuvent limiter le nombre de décimales acceptées).
Søren Boisen
11
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss zzz");

DateTime.Now.ToString("O");

REMARQUE: En fonction de la conversion que vous effectuez de votre côté, vous utiliserez la première ligne (la plus semblable) ou la seconde.

Assurez-vous d'appliquer le format uniquement à l'heure locale, car "zzz" correspond aux informations de fuseau horaire pour la conversion UTC.

image

PSM
la source
Je ne suis pas si sûr de #ChrisHynes car il pose des questions sur la suggestion que j'ai faite concernant la première ligne de code, mais si vous avez raison et c'est le cas, la réponse est "ReSharper"
PSM
9

Le "s"spécificateur de format standard représente une chaîne de format de date et heure personnalisée définie par la propriété DateTimeFormatInfo.SortableDateTimePattern . Le modèle reflète une norme définie ( ISO 8601 ) et la propriété est en lecture seule. Par conséquent, il est toujours le même, quelle que soit la culture utilisée ou le fournisseur de format fourni. La chaîne de format personnalisé est "yyyy'-'MM'-'dd'T'HH':'mm':'ss".

Lorsque ce spécificateur de format standard est utilisé, l'opération de formatage ou d'analyse utilise toujours la culture invariante.

- depuis MSDN

Amal
la source
1
Il est donc correct de l'utiliser .ToString("s")?
AhmetB - Google
Je le crois. - Tant que votre exigence correspond à la question d'origine qui est .. Mais jetez un œil à l'avertissement de Simon Wilson ci
Amal
9

Pour convertir DateTime.UtcNow en une représentation sous forme de chaîne aaaa-MM-jjTHH: mm: ssZ , vous pouvez utiliser la méthode ToString () de la structure DateTime avec une chaîne de mise en forme personnalisée. Lorsque vous utilisez des chaînes de format personnalisé avec un DateTime, il est important de se rappeler que vous devez échapper à vos séparateurs à l'aide de guillemets simples.

Ce qui suit renverra la représentation de chaîne que vous vouliez:

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

Il est intéressant de noter que le format personnalisé "aaaa-MM-jjTHH: mm: ssK" (sans ms) est la méthode de formatage la plus rapide.

Il est également intéressant de noter que le format "S" est lent sur Classic et rapide sur Core ...

Bien sûr, les nombres sont très proches, entre certaines lignes, la différence est insignifiante (les tests avec suffixe _Verifysont les mêmes que ceux qui n'en ont pas, démontrent la répétabilité des résultats)

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 a été utilisé

Roman Pokrovskij
la source
3

En utilisant Newtonsoft.Json, vous pouvez faire

JsonConvert.SerializeObject(DateTime.UtcNow)

Exemple: https://dotnetfiddle.net/O2xFSl

blackforest-tom
la source
1
meilleure réponse ici.
L'intégrateur le
2

Si vous développez sous SharePoint 2010 ou supérieur, vous pouvez utiliser

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
Simon Logic
la source
20
SharePoint, lorsque votre .Net n'est pas assez Java.
Henrik
18
Utiliser SharePoint pour cela, c'est un peu comme apporter un pot de gelée, une boîte d'allumettes mouillées et 2 chimpanzés qui marchent sur trapèze pour une fusillade.
nathanchere
Même dans SharePoint nous espérons que vous pouvez utiliser de la BCL .ToString("o")mieux ou, $"My complicated string {dt:o}".
binki
2

Pour formater comme 2018-06-22T13: 04: 16 qui peut être passé dans l'URI d'une utilisation d'API:

public static string FormatDateTime(DateTime dateTime)
{
    return dateTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
}
Nick Gallimore
la source
1
Je pense que cette chaîne de date ISO est invariante à la culture par définition.
Jonas
1

Comme mentionné dans d'autres réponses, DateTimea des problèmes de conception.

NodaTime

Je suggère d'utiliser NodaTime pour gérer les valeurs de date / heure:

  • Heure locale, date, datetime
  • Heure mondiale
  • Temps avec fuseau horaire
  • Période
  • Durée

Mise en page

Ainsi, pour créer et formater, ZonedDateTimevous pouvez utiliser l'extrait de code suivant:

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

Pour moi, le NodaTimecode semble assez verbeux. Mais les types sont vraiment utiles. Ils aident à gérer correctement les valeurs de date / heure.

Newtonsoft.Json

Pour l'utiliser NodaTimeavec, Newtonsoft.Jsonvous devez ajouter une référence au NodaTime.Serialization.JsonNetpackage NuGet et configurer les options JSON.

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