Учитывая объект DateTime, как я могу получить дату ISO 8601 в строковом формате?

791

Данный:

DateTime.UtcNow

Как получить строку, которая представляет такое же значение в формате, совместимом с ISO 8601 ?

Обратите внимание, что ISO 8601 определяет ряд похожих форматов. Конкретный формат, который я ищу:

yyyy-MM-ddTHH:mm:ssZ
Iain
источник

Ответы:

781

Примечание для читателей: несколько комментаторов указали на некоторые проблемы в этом ответе (особенно связанные с первым предложением). Обратитесь к разделу комментариев для получения дополнительной информации.

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

Параметры форматирования даты и времени

Wayne
источник
20
В наши дни выполнение этого (попытка визуализировать время UTC со смещением, что не имеет большого смысла) выдает исключение. Итак, я согласен с другими, что формат "s" с инвариантной культурой, вероятно, является более правильным. К сведению, сообщение formatexception выглядит так: «DateTime UTC преобразуется в текст в формате, который корректен только для местного времени. Это может произойти при вызове DateTime.ToString с использованием спецификатора формата« z », который будет включать смещение локального часового пояса. в выходной. "
Том Лианца
9
Я живу в Австралии, и мне пришлось использовать ToString("yyyy-MM-ddTHH:mm:ssK")это для работы (с плагином jquery timeago, который я использовал).
Goneale
6
Если вы хотите включить смещение часового пояса, сделайте это: dt.ToString("s") + dt.ToString("zzz")// 2013-12-05T07: 19: 04-08: 00
alekop
4
Косая черта (\ :) вызывает проблемы со строкой ..., вставляя символ @ для использования строкового литерала.
Гиги
6
@core: это один из стандартных форматов, который отличается от пользовательских связанных форматов: msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
Уэйн
361

DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)должен дать вам то, что вы ищете, поскольку спецификатор формата "s" описывается как сортируемый шаблон даты / времени; соответствует ISO 8601

Саймон Уилсон
источник
34
Я считаю, что это правильный ответ. Нет смысла явно определять yyyy-MM-etc, если Microsoft уже внедрила ISO 8601. Ответ Iain тоже был правильным, но вы всегда должны указывать InvariantCulture (или любую другую CultureInfo) по нескольким причинам (т.е. никогда не предполагайте, что .NET должен просто предположим). Вы также можете использовать: DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.SortableDateTimePattern); Однако, поскольку все они исключают часовой пояс и т. Д., У вас может не быть иного выбора, кроме как использовать явный форматер, например:"yyyy-MM-ddTHH:mm:ss.fffZ"
Джон Дэвис,
20
Несмотря на то, что он соответствует, он не учитывает часовой пояс и Zвыглядит примерно так: DateTime.UtcNow.ToString(c, CultureInfo.InvariantCulture)) => 2012-06-26T11:55:36и нет миллисекундного разрешения, которое было бы очень приятно иметь, поскольку компьютеры совершали значительное количество тактов в секунду.
Хенрик
9
Когда 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 (.)
Хенрик,
2
@binki - теперь я в замешательстве. В соответствии с документацией, на которую я ссылался ранее для SortableDateTimePattern , говорится, что она должна соответствовать конкретной культуре. ОДНАКО, это кажется противоречащим его собственным примерам (так как они все выглядят одинаково); попробуй DateTime.Now.ToString("s", new CultureInfo(myCulture)).
drzaus
88
DateTime.UtcNow.ToString("s")

Возвращает что-то вроде 2008-04-10T06: 30: 00

UtcNowочевидно, возвращает время UTC, поэтому нет никакого вреда в:

string.Concat(DateTime.UtcNow.ToString("s"), "Z")
Iain
источник
11
Просто из интереса: почему string.Concat (), а не '+'?
Даниэль Фортунов
2
Хаббит, есть ли разница?
Иэн
84
@KoenZomers: Я не думаю, что это правильно. Я думаю, что a + bкомпилируется с тем же промежуточным кодом, что и string.Concat(a, b)(при условии, что a и b являются строками, конечно), поэтому нет никакой разницы в производительности или потреблении памяти.
Марк Байерс
78
Да, Марк прав. Коен, вы только что попали в ловушку нелепо преждевременной микрооптимизации, даже если вы правы.
Нолдорин
7
@ greg84: Ну, вы не совсем правы. Посмотрите на этот пост архитектора Microsoft Рико Мариани: blogs.msdn.com/b/ricom/archive/2003/12/15/43628.aspx - он говорит, что + b действительно компилируется в concat +, есть еще немного информации о правильном использовании StringBuilder.
mrówa
37

Использование:

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

Источники:

дон
источник
2
кажется, что вы стали жертвой копирования по местному обычаю ;-) string strLocalTimeAndOffset_custom = localTimeAndOffset.ToString("yyyy-MM-ddTHH:mm:ssK");приведет к:strLocalTimeAndOffset_custom: 2012-09-17T22:02:51-07:00
Холли
oэто формат ISO-8601.
Юша Алеауб
33
System.DateTime.UtcNow.ToString("o")

=>

val it : string = "2013-10-13T13:03:50.2950037Z"
Хенрик
источник
Согласитесь, это единственный способ быть абсолютно уверенным, что у вас есть однозначная дата / время в любом часовом поясе
Мэтт Вилко,
23

Вы можете получить «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.Unspecified

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)

Oaxas
источник
20

Если вы должны использовать 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.

Алекс Ноласко
источник
2
ISO8601 используется в страве для одного. Однако, пожалуйста, используйте: StartTime.ToString ("гггг-ММ-ддТЧЧ: мм: ссЗ"), а не ToString ("о"), который добавляет миллисекунды и т. Д.
peterincumbria
2
Для меня "yyyy-MM-dd-THH: mm: ssZ" буквально вывело "Z" в конце моей строки вместо маркера часового пояса, который не сделал то, что я хотел. ToString ("o") фактически сделал то, что мне было нужно, намного проще и короче.
Блэр Коннолли
18

Удивило, что никто не предложил это:

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 *****
rburte
источник
1
Принятый ответ «o» работает, но он дает раздражающее количество точности (geez .XXXXXXX секунд), в то время как я предпочитаю это, так как он останавливается на секундах.
Джоккинг
Также этот документ утверждает, что "u" - это ISO 8601, но что с пробелом вместо T? Соберись Microsoft
jhocking
@jhocking en.wikipedia.org/wiki/ISO_8601#cite_note-30 ISO 8601 является относительно допустимым, если вы прочитаете его ...
19
16

Я бы просто использовал XmlConvert:

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

Это автоматически сохранит часовой пояс.

Sumrak
источник
Я пошел дальше и добавил метод расширения. открытый статический класс DateTimeExtensions {открытая статическая строка ToIsoFormat (this DateTime dateTime) {return XmlConvert.ToString (dateTime, XmlDateTimeSerializationMode.RoundtripKind); }}
убийство
14

У большинства из этих ответов есть миллисекунды / микросекунды, которые явно не поддерживаются ISO 8601. Правильный ответ будет:

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

Ссылки:

Джастин тернер
источник
15
Прочитайте свою собственную ссылку на Википедию в разделе «Times». В нем упоминается «Десятичные дроби», что означает, что ISO 8601 поддерживает как миллисекунды, так и микросекунды (но стороны, принимающие участие в сообщении, могут ограничивать количество принятых десятичных знаков).
Сёрен Буазен
11
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss zzz");

DateTime.Now.ToString("O");

ПРИМЕЧАНИЕ. В зависимости от того, какую конверсию вы выполняете, вы будете использовать первую строку (наиболее понравившуюся) или вторую.

Обязательно применяйте формат только по местному времени, так как «zzz» - это информация о часовом поясе для преобразования в UTC.

образ

PSM
источник
Я не уверен в этом #ChrisHynes, так как он спрашивает о предложении, которое я сделал относительно первой строки кода, но если вы правы, и в этом случае ответ «ReSharper»
PSM
9

Спецификатор "s"стандартного формата представляет собой пользовательскую строку формата даты и времени, которая определяется свойством DateTimeFormatInfo.SortableDateTimePattern . Шаблон отражает определенный стандарт ( ISO 8601 ), и свойство доступно только для чтения. Поэтому оно всегда одинаково, независимо от используемой культуры или поставщика формата. Строка пользовательского формата "yyyy'-'MM'-'dd'T'HH':'mm':'ss".

Когда используется этот стандартный спецификатор формата, операция форматирования или синтаксического анализа всегда использует инвариантную культуру.

- из MSDN

Амаль
источник
1
Так что это нормально использовать .ToString("s")?
AhmetB - Google
Я так считаю. - Пока ваше требование соответствует первоначальному вопросу, который ... Но взгляните на предупреждение Саймона Уилсона ниже
Амаль
9

Чтобы преобразовать DateTime.UtcNow в строковое представление yyyy-MM-ddTHH: mm: ssZ , вы можете использовать метод ToString () структуры DateTime с пользовательской строкой форматирования. При использовании строк нестандартного формата с DateTime важно помнить, что вам нужно экранировать разделители, используя одинарные кавычки.

Следующее вернет желаемое строковое представление:

DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", DateTimeFormatInfo.InvariantInfo)
Оппозиционный
источник
9

Интересно, что пользовательский формат «гггг-мм-ддтчч: мм: сск» (без мс) - самый быстрый метод форматирования.

Также интересно, что формат "S" медленный на Классическом и быстрый на 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 был использован

Роман Покровский
источник
3

Используя Newtonsoft.Json, вы можете сделать

JsonConvert.SerializeObject(DateTime.UtcNow)

Пример: https://dotnetfiddle.net/O2xFSl

Blackforest-том
источник
1
лучший ответ здесь.
Интегратор
2

Если вы разрабатываете под SharePoint 2010 или выше, вы можете использовать

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
Саймон Лоджик
источник
20
SharePoint, когда ваш .Net не достаточно Java.
Хенрик
18
Использование SharePoint для этого похоже на то, чтобы принести ванну желе, мокрую коробку спичек и двух шимпанзе, ходящих по трапеции, в перестрелку.
Натанчер
Даже в SharePoint , надеюсь , вы можете использовать BCL, .ToString("o")или, лучше, $"My complicated string {dt:o}".
Бинки
2

Для форматирования, например 2018-06-22T13: 04: 16, который можно передать в URI API, используйте:

public static string FormatDateTime(DateTime dateTime)
{
    return dateTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
}
Ник Галлимор
источник
1
Я думаю, что эта строка даты ISO является культурно-инвариантной для каждого определения.
Джонас
1

Как уже упоминалось в другом ответе, DateTimeимеет проблемы с дизайном.

NodaTime

Я предлагаю использовать 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код выглядит довольно многословно. Но типы действительно полезны. Они помогают правильно обрабатывать значения даты / времени.

Newtonsoft.Json

Для использования NodaTimeс Newtonsoft.Jsonвам нужно добавить ссылку на NodaTime.Serialization.JsonNetNuGet пакет и параметры настраивают JSON.

services
    .AddMvc()
    .AddJsonOptions(options =>
    {
        var settings=options.SerializerSettings;
        settings.DateParseHandling = DateParseHandling.None;
        settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
    });
Владимир Серых
источник