Я понимаю, что есть много тем о разборе дат твиттера, но у меня особая проблема, и я не смог найти никаких тем, относящихся к этому.
Я получаю это сообщение: https://twitter.com/bodegamcallen/status/1033757489567805440
дата создания которого - 26.08.2018 в 9:46 Central Time.
Дата создания в API следующая: «Вс, 26 августа, 16:46:06 +0000 2018».
Это имеет смысл, поскольку 16:46 (14:46) UTC - это 9:46 AM по центральному времени (-500).
Однако я разбираю это с помощью этого кода:
statusModel.DatePosted = DateTime.ParseExact(
this.created_at, "ddd MMM dd HH:mm:ss zzzz yyyy",
CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal);
и вместо того, чтобы получить желаемое время UTC, показанное выше, я получаю это: 26.08.2018 16:46:06
Если я изменю DateTimeStyle на None или AssumeLocal, я получу следующее: 26.08.2018 11:46:06
Ни то, ни другое не правильно!
Я пробовал разные форматы из других потоков, например:
Я также попытался использовать DateTimeOffset.Parse и изменить культуру на мою (en-us)
все они дают мне одинаковые результаты.
Что я делаю не так? Как сделать так, чтобы дата и время совпадали со временем в формате UTC и значением даты, которое я получаю от API?
🤔 А знаете ли вы, что...
C# обладает сборщиком мусора, который автоматически управляет памятью, что снижает риск утечек памяти.
Ага! Оказалось, что настройки моей учетной записи Twitter были настроены на тихоокеанское время, а не на центральное время, и это объясняет разницу в два часа.
Я изменил настройки часового пояса для своей учетной записи, как описано здесь: https://help.twitter.com/en/managing-your-account/how-to-change-time-zone-settings
А после перехода на центральное время данные API поступают правильно!
надеюсь, что это поможет кому-то другому. Часовые пояса, амирит?
Несколько вещей:
zzzz
не является допустимым спецификатором. Всегда проверяйте эти документы, если сомневаетесь.K
- единственный спецификатор часового пояса, который подходит для синтаксического анализа DateTime
. Остальные (z
, zz
и zzz
) предназначены для синтаксического анализа DateTimeOffset
.+0000
или Z
), DateTime.Parse
и DateTime.ParseExact
по умолчанию предполагают, что вы хотите, чтобы тип вывода был DateTimeKind.Local
, и что вы хотите, чтобы значение было скорректировано на локальное, независимо от того, что это во входной строке. Изучите выходной .Kind
, если вы не уверены, что он работает правильно. Если вы хотите вместо этого использовать UTC, вы должны передать DateTimeStyles.AdjustToUniversal
.DateTimeStyles.AssumeUniversal
, потому что во входной строке присутствует информация о часовом поясе.CultureInfo.InvariantCulture.DateTimeFormat
. Достаточно и чаще всего пройти CultureInfo.InvariantCulture
.Собирая все это вместе, ваш код должен быть:
statusModel.DatePosted = DateTime.ParseExact(
this.created_at, "ddd MMM dd HH:mm:ss K yyyy",
CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
И, конечно же, вы избавите себя от лишних хлопот и путаницы, если замените свой DatePosted
на тип DateTimeOffset
. Это лучше для такого рода сценариев, и тогда вам не нужно беспокоиться о DateTimeKind
или DateTimeStyles
.