Donné:
DateTime.UtcNow
Comment obtenir une chaîne représentant la même valeur dans un format conforme à ISO 8601 -?
Notez que l'ISO 8601 définit un certain nombre de formats similaires. Le format spécifique que je recherche est:
yyyy-MM-ddTHH:mm:ssZ
Note aux lecteurs: Plusieurs intervenants ont signalé des problèmes dans cette réponse (liés en particulier à 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");
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")
DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)
devrait vous indiquer ce que vous recherchez, car le spécificateur de format "s" est décrit comme un modèle de date/heure pouvant être trié; conforme à la norme ISO 8601.
DateTime.UtcNow.ToString("s")
Retourne quelque chose comme 2008-04-10T06: 30: 00
UtcNow
retourne évidemment un UTC donc il n'y a pas de mal à:
string.Concat(DateTime.UtcNow.ToString("s"), "Z")
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/>");
}
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
System.DateTime.UtcNow.ToString("o")
=>
val it : string = "2013-10-13T13:03:50.2950037Z"
Vous pouvez obtenir le "Z" ( ISO 8601UTC) 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 enum 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 obtiendrez peut-être résultats différents, je ne sais pas s’il s’agit d’un bogue, mais dans ce cas, vous obtiendrez de meilleurs résultats avec une variable String si vous effectuez un débogage.
Source: chaînes de format de date et d'heure standard (MSDN)
Si vous devez utiliser DateTime selon ISO 8601, alors ToString ("o") devrait donner ce que vous recherchez. Par exemple,
2015-07-06T12:08:27
Cependant, DateTime + TimeZone peut présenter d'autres problèmes, décrits dans l'article du blog DateTime et DateTimeOffset dans .NET: bonnes pratiques et pièges courants:
DateTime contient d'innombrables pièges conçus pour donner des bogues à votre code:
1.- Les valeurs DateTime avec DateTimeKind.Unspecified sont une mauvaise nouvelle.
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.
Je voudrais juste utiliser XmlConvert
NAME _ :
XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.RoundtripKind);
Cela préservera automatiquement le fuseau horaire.
La plupart de ces réponses ont des millisecondes/microsecondes qui ne sont clairement pas prises en charge par ISO 8601. La réponse correcte serait:
System.DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssK");
// or
System.DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");
Références:
Pour convertir DateTime.UtcNow en une représentation sous forme de chaîne de 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ées avec DateTime, il est important de vous rappeler que vous devez échapper à vos séparateurs à l'aide de guillemets simples.
Les éléments suivants renverront la représentation de chaîne souhaitée:
DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", DateTimeFormatInfo.InvariantInfo)
Le spécificateur de format standard
"s"
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 identique, indépendamment de la culture utilisée ou du fournisseur de format fourni. La chaîne de format personnalisée 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.
- de MSDN
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss zzz");
DateTime.Now.ToString("O");
REMARQUE: Selon la conversion que vous effectuez de votre côté, vous utiliserez la première ligne (la plus semblable) ou la deuxième.
Veillez à appliquer le format uniquement à l'heure locale, car "zzz" correspond aux informations de fuseau horaire pour la conversion en temps UTC.
Il est intéressant de noter que le format personnalisé "aaaa-MM-jjTHTH: 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, la différence entre certaines lignes est insignifiante (les tests avec le suffixe _Verify
sont les mêmes que ceux sans suffixe, ils 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é
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);
}
Surpris que personne ne l'ait suggéré:
System.DateTime.UtcNow.ToString("u").Replace(' ','T')
Le niversalSortableDateTimePattern vous amène presque entièrement à ce que vous voulez (ce qui est davantage une représentation RFC 3339 ).
Si vous développez sous SharePoint 201 ou supérieur, vous pouvez utiliser
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
En utilisant Newtonsoft.Json, vous pouvez faire
JsonConvert.SerializeObject(DateTime.UtcNow)
Exemple: https://dotnetfiddle.net/O2xFSl