Відповіді:
Зауважте читачам: Кілька коментаторів вказали на деякі проблеми у цій відповіді (зокрема, стосовно першої пропозиції). Для отримання додаткової інформації зверніться до розділу коментарів.
DateTime.UtcNow.ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");
Це дає вам дату, схожу на 2008-09-22T13: 57: 31.2311892-04: 00 .
Інший спосіб:
DateTime.UtcNow.ToString("o");
що дає вам 2008-09-22T14: 01: 54.9571247Z
Щоб отримати вказаний формат, ви можете використовувати:
DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")
ToString("yyyy-MM-ddTHH:mm:ssK")для цього роботу (з плагіном jquery timeago, який я використовував).
dt.ToString("s") + dt.ToString("zzz")// 2013-12-05T07: 19: 04-08: 00
DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)повинен дати вам те, що ви шукаєте, оскільки специфікатор формату "s" описується як сортований шаблон дати / часу; відповідає ISO 8601.
DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.SortableDateTimePattern); Однак, оскільки все це виключає часовий пояс тощо, у вас може не залишитися іншого вибору, крім використання явного форматера, тобто"yyyy-MM-ddTHH:mm:ss.fffZ"
Zвиглядаючи так: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36і немає мілісекундної роздільної здатності, яку дуже приємно мати, оскільки комп'ютери роблять досить багато кліщів в секунду.
oтобою ви отримуєте 2012-06-26T11:55:36.1007668Zзначення 36.1007668секунд, тому ви отримуєте дозвіл до 1/10^7секунди. З 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"немає сенсу, оскільки: "" O "(або" o ")," R "(або" r ")," s "і" u ". Ці рядки відповідають рядкам на замовлення формату, визначеним інваріантною культурою. Вони створюють рядкові подання значень дати та часу, які мають бути однаковими для різних культур ».
DateTime.Now.ToString("s", new CultureInfo(myCulture)).
DateTime.UtcNow.ToString("s")
Повертає щось на зразок 2008-04-10T06: 30: 00
UtcNowочевидно повертає час за UTC, тому немає ніякої шкоди в:
string.Concat(DateTime.UtcNow.ToString("s"), "Z")
a + bкомпілюється до того ж проміжного коду, що і string.Concat(a, b)(якщо, звичайно, a і b є рядками), тому різниці у продуктивності та витраті пам'яті немає.
Використання:
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");призвело б до:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
System.DateTime.UtcNow.ToString("o")
=>
val it : string = "2013-10-13T13:03:50.2950037Z"
Ви можете отримати "Z" ( ISO 8601 UTC ) із наступним кодом:
Dim tmpDate As DateTime = New DateTime(Now.Ticks, DateTimeKind.Utc)
Dim res as String = tmpDate.toString("o") '2009-06-15T13:45:30.0000000Z
Ось чому:
ISO 8601 мають різні формати:
DateTimeKind.Local
2009-06-15T13:45:30.0000000-07:00
DateTimeKind.Utc
2009-06-15T13:45:30.0000000Z
DateTimeKind.Unspeted
2009-06-15T13:45:30.0000000
.NET пропонує нам перелік таких варіантів:
'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")
Примітка : Якщо ви застосуєте "утиліту перегляду" Visual Studio 2008 до частини toString ("o"), ви можете отримати різні результати, я не знаю, чи це помилка, але в цьому випадку у вас кращі результати за допомогою змінної String якщо ви налагоджуєте.
Джерело: Стандартні рядки формату дати та часу (MSDN)
Якщо вам потрібно використовувати DateTime до ISO 8601, то ToString ("o") повинен отримати те, що ви шукаєте. Наприклад,
2015-07-06T12:08:27
Однак DateTime + TimeZone може створити інші проблеми, як описано в публікаціях блогу DateTime та DateTimeOffset в .NET: Добрі практики та загальні помилки :
DateTime має незліченну кількість пасток, які розроблені для надання вашим кодам помилок:
1.- Значення DateTime з DateTimeKind.Unspecified - це погані новини.
2.- DateTime не хвилює UTC / Local при порівнянні.
3.- Значення DateTime не відомі рядкам стандартного формату.
4.- Розбір рядка, який має маркер UTC з DateTime, не гарантує часу UTC.
Здивовано, що ніхто не запропонував цього:
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
UniversalSortableDateTimePattern отримує вас майже весь шлях до того , що ви хочете (який є більше RFC 3339 уявлення).
Додано: я вирішив використати орієнтири, відповіді на які https://stackoverflow.com/a/43793679/653058, щоб порівняти, як це відбувається.
тл: д-р; на кінці дорогого кінця, але все-таки трохи більше половини мілісекунди на моєму балаканому старому ноутбуці :-)
Впровадження:
[Benchmark]
public string ReplaceU()
{
var text = dateTime.ToUniversalTime().ToString("u").Replace(' ', 'T');
return text;
}
Результати:
// * 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 *****
Я просто використовую XmlConvert:
XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.RoundtripKind);
Він автоматично збереже часовий пояс.
Більшість із цих відповідей мають мілісекунди / мікросекунди, що явно не підтримується ISO 8601. Правильною відповіддю буде:
System.DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssK");
// or
System.DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");
Список літератури:
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss zzz");
DateTime.Now.ToString("O");
ПРИМІТКА. Залежно від конверсії, яку ви робите в кінці, ви будете використовувати перший рядок (найбільше сподобався) або другий.
Переконайтеся, що застосований формат використовується лише за місцевим часом, оскільки "zzz" - це інформація про часовий пояс для перетворення UTC.

"s"Стандартний формат специфікатор є рядком формату дати і часу, яке визначається в DateTimeFormatInfo.SortableDateTimePattern власності. Шаблон відображає визначений стандарт ( ISO 8601 ), а властивість лише для читання. Тому він завжди однаковий, незалежно від використовуваної культури чи постачальника формату. Рядок спеціального формату є"yyyy'-'MM'-'dd'T'HH':'mm':'ss".Коли використовується цей стандартний специфікатор формату, операція форматування або розбору завжди використовує інваріантну культуру.
- від MSDN
.ToString("s")?
Щоб конвертувати DateTime.UtcNow до рядкового подання yyyy-MM-ddTHH: mm: ssZ , ви можете використовувати метод ToString () структури DateTime зі спеціальним рядком форматування. Використовуючи рядки власного формату з DateTime, важливо пам’ятати, що вам потрібно уникнути своїх сепараторів, використовуючи одинарні лапки.
Нижче наведено потрібне представлення рядків:
DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", DateTimeFormatInfo.InvariantInfo)
Цікаво, що користувацький формат "yyyy-MM-ddTHH: mm: ssK" (без ms) - це найшвидший метод форматування.
Також цікаво, що формат "S" повільний на Classic і швидкий на Core ...
Зрозуміло, цифри дуже близькі, різниця між рядками незначна (тести з суфіксом _Verifyтакі самі, як і без суфікса, демонструє повторюваність результатів)
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 |
Код:
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 було використано
Використовуючи Newtonsoft.Json, ви можете зробити
JsonConvert.SerializeObject(DateTime.UtcNow)
Приклад: https://dotnetfiddle.net/O2xFSl
Якщо ви розробляєте під SharePoint 2010 або новішою, ви можете використовувати
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
.ToString("o")або, краще, $"My complicated string {dt:o}".
Для форматування на зразок 2018-06-22T13: 04: 16, який можна передавати в URI API, використовуйте:
public static string FormatDateTime(DateTime dateTime)
{
return dateTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
}
Як згадувалося в іншій відповіді, DateTimeє питання за дизайном
Я пропоную використовувати NodaTime для управління значеннями дати / часу:
Отже, для створення та форматування ZonedDateTimeви можете використовувати такий фрагмент коду:
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
Для мене NodaTimeкод виглядає досить багатослівно. Але типи справді корисні. Вони допомагають правильно обробляти значення дати / часу.
Для використання
NodaTimeзNewtonsoft.Jsonвас виникла необхідність створення посилання наNodaTime.Serialization.JsonNetNuGet пакет і параметри налаштовують JSON.
services
.AddMvc()
.AddJsonOptions(options =>
{
var settings=options.SerializerSettings;
settings.DateParseHandling = DateParseHandling.None;
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
});