Запись и чтение даты из JSON

                   JObject j = new JObject();
                   j["dateCreated"] = fileInfo.CreationTime;

пишет так:

              "dateCreated": "2021-10-14T01:05:13.8761652+07:00"

А как это прочитать обратно в DateTime?

JSON тут не причем, в строке может быть что угодно.

Похоже, это ISO-8601.

https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings#Roundtrip

using System;
using System.Globalization;

public class Program
{
	public static void Main()
	{
		var dt = DateTime.Parse("2021-10-14T01:05:13.8761652+07:00", null, DateTimeStyles.RoundtripKind);
		Console.WriteLine(dt.ToString("o"));
	}
}

https://dotnetfiddle.net/bYCIF0

Да я знаю, но просто по-умолчанию в таком формате пишет.
Странно. А при чтении получается 11/15/2021 16:05:33 :thinking: Почему?
по-этому, можно так:


            string t = json.Value<string>("buildDate");
            DateTime d = DateTime.ParseExact(t, "MM/dd/yyyy HH:mm:ss",
                CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);

При чтении как?

При выводе может получиться на день раньше если часовой пояс выводится +0 вместо +7.

JObject j = new JObject();
j["dateCreated"] = fileInfo.CreationTime;

Пишется такая строка: 2021-10-14T16:05:13.8761652+07:00

Читаем:


        private void OpenJson(string fn)
        {
            JObject json = JObject.Parse(File.ReadAllText(fn));
            string t = json.Value<string>("buildDate");
            dateCreated = DateTime.ParseExact(t, "MM/dd/yyyy HH:mm:ss",
                CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
        }

Получается такая: 10/14/2021 16:05:13
:man_shrugging:

Это ж разные вещи :man_shrugging:

Выводится-то с каким часовым поясом?

По умолчанию вроде используется текущий на компе, так что

выведет например 2021-10-13T21:05:13.8761652+03:00 если +3.

Converting times between time zones | Microsoft Docs

Поэтому совсем не факт, что

это правильный результат (совпадает с поясом пользователя). Тут же теряется инфа о часовом поясе.

buildDate это поле в JSON’е, а dateCreated это название переменной. Почему разные? :thinking: По-моему, суть одна.

просто выводится :man_shrugging: ToString() (временно)

А как читать, чтобы не терялась?

так я про поля


Например так

А! Это я просто на форуме код вручную писал и имя перепутал. В реальном коде правильно написано.

Но ведь из JSON’а строка с датой вычитывается не так.

В смысле? :confusedparrot:

Ну я же говорю:
Пишется так: 2021-10-14T16:05:13.8761652+07:00
А при чтении выдаёт: 10/14/2021 16:05:13

{
  "buildDate": "2021-11-15T16:05:33.6206992+07:00",
  "list": []
}

            string t = json.Value<string>("buildDate");

выдаёт 11/15/2021 16:05:33

Так и что не так?))

Если речь о форматировании, то это в параметрах ToString задается.

выдаст как было (ISO-8601).

:thinking: это точно именно в t?

Это чей ToString?

Да. Только что перепроверил.

Если это Newtonsoft.Json, то видимо оно само даты парсит. Так что можно доставать сразу дату, а не строку.

Во! Точно

            dateCreated = json.Value<DateTime>("buildDate");

Не знал, что так можно. Но это логично. Если писать сам умеет, то и читать тоже должен сам.

Объясните ещё такой момент. Хочу сконвертить XML (созданные в Delphi) в JSON.
В XML прописаны аттрибуты с датой: build_date="09.01.2020 12:55:13".
Читаю так:

                        string t = rootNode.Attributes["build_date"].Value;
                        dateCreated = DateTime.ParseExact(t, "dd.MM.yyyy HH:mm:ss",
                            CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal);
                        lblDateModified.Text = $"Изменён: {dateCreated}";

При записи в JSON, получается так: "buildDate": "2020-01-09T12:55:13+07:00". Время правильное, но добавлен часовой пояс (который в винде стоит).

А если вместо AssumeLocal ставить AssumeUniversal, то дата читается и пишется как 2020-01-09T19:55:13+07:00. Это значит 12 + 7 = 19. Это неправильное время. Но почему в обоих случаях добавляется часовой пояс? :thinking:

Так и чем он мешает? Он же как раз и добавлен, чтобы у пользователя из другого пояса оно тоже прочиталось правильно.

Либо так, либо надо в UTC+0 писать (09.01.2020 05:55:13) и использовать AssumeUniversal.
Как иначе пояс угадать?

Ничем не мешает. Просто не понятно, дата записана уже с учётом пояса, или пояс будет учтён во время чтения? :thinking:

Записана в том поясе, который указан в конце.

https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators

Если читать например так

то будет учтен, независимо от пояса на компе.

Но ведь Newtonsoft сам ее парсит

           DateTime dateCreated = json.Value<DateTime>("buildDate");

вот мне и не понятно 2020-01-09T12:55:13+07:00 это уже с учётом или без. Но вы уже сказали, что с учётом.