Réponses:
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")
ToString("yyyy-MM-ddTHH:mm:ssK")
pour que cela fonctionne (avec le plugin jquery timeago que j'utilisais).
dt.ToString("s") + dt.ToString("zzz")
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.
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"
Z
ressemblant à ceci: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36
et 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.
o
vous obtenez des secondes 2012-06-26T11:55:36.1007668Z
significatives 36.1007668
, vous obtenez donc une résolution jusqu'à 1/10^7
une 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 (.)
"s"
n'a aucun sens car: "" O "(ou" o ")," R "(ou" r ")," s "et" u ". Ces chaînes correspondent à des chaînes de format personnalisé définies par la culture invariante. Ils produisent des représentations de chaînes de valeurs de date et d'heure qui sont censées être identiques d'une culture à l'autre. »
DateTime.Now.ToString("s", new CultureInfo(myCulture))
.
DateTime.UtcNow.ToString("s")
Renvoie quelque chose comme 2008-04-10T06: 30: 00
UtcNow
renvoie évidemment une heure UTC donc il n'y a aucun mal à:
string.Concat(DateTime.UtcNow.ToString("s"), "Z")
a + b
compile 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.
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
string strLocalTimeAndOffset_custom = localTimeAndOffset.ToString("yyyy-MM-ddTHH:mm:ssK");
entraînerait:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
o
est un format ISO-8601.
System.DateTime.UtcNow.ToString("o")
=>
val it : string = "2013-10-13T13:03:50.2950037Z"
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)
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.
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 *****
Je voudrais simplement utiliser XmlConvert
:
XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.RoundtripKind);
Il conservera automatiquement le fuseau horaire.
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:
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.
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
.ToString("s")
?
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)
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 _Verify
sont 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é
En utilisant Newtonsoft.Json, vous pouvez faire
JsonConvert.SerializeObject(DateTime.UtcNow)
Exemple: https://dotnetfiddle.net/O2xFSl
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)
.ToString("o")
mieux ou, $"My complicated string {dt:o}"
.
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);
}
Comme mentionné dans d'autres réponses, DateTime
a des problèmes de conception.
Je suggère d'utiliser NodaTime pour gérer les valeurs de date / heure:
Ainsi, pour créer et formater, ZonedDateTime
vous 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 NodaTime
code semble assez verbeux. Mais les types sont vraiment utiles. Ils aident à gérer correctement les valeurs de date / heure.
Pour l'utiliser
NodaTime
avec,Newtonsoft.Json
vous devez ajouter une référence auNodaTime.Serialization.JsonNet
package NuGet et configurer les options JSON.
services
.AddMvc()
.AddJsonOptions(options =>
{
var settings=options.SerializerSettings;
settings.DateParseHandling = DateParseHandling.None;
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
});