Парсинг Twitter создан на дату как UTC - PullRequest
0 голосов
/ 28 августа 2018

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

Я получаю это сообщение: https://twitter.com/bodegamcallen/status/1033757489567805440

с датой создания 8/26/2018 в 9:46 Центральное время.

Дата создания в API: «Sun Aug 26 16:46:06 +0000 2018»

Что имеет смысл как 16:46 вечера (2:46 вечера) UTC 9:46 утра по центральному (-500).

Однако, я анализирую это, используя этот код:

statusModel.DatePosted = DateTime.ParseExact(
    this.created_at, "ddd MMM dd HH:mm:ss zzzz yyyy", 
    CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal);

и вместо того, чтобы получить желаемое время UTC, показанное выше, я получаю это: 8/26/2018 4:46:06 PM

Если я изменю DateTimeStyle на None или AssumeLocal, я получу это: 8/26/2018 11:46:06 AM

Ничего из этого не верно!

Я пробовал разные форматы из других тем, например:

  • "ддд ммм дд чч: мм: сс к гггг"
  • "ддд ммм дд чч: мм: сс з гггг"
  • "ддд ммм дд чч: мм: сс зззгггг"
  • "ддд ммм дд чч: мм: сс + фффф гггг"

Я также попытался использовать DateTimeOffset.Parse и изменить культуру на мою (en-us)

они все дают мне одинаковые результаты.

Что я делаю не так? Как сделать так, чтобы дата и время совпадали с временем UTC, равным значению даты, которое я получаю из API?

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Несколько вещей:

  • 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.

0 голосов
/ 28 августа 2018

Aha! Оказывается, мои настройки учетной записи в твиттере были настроены на тихоокеанское время, а не на центральное, и это будет учитывать разницу в два часа.

Я изменил настройки часового пояса для своей учетной записи, как описано здесь: https://help.twitter.com/en/managing-your-account/how-to-change-time-zone-settings

А после перехода на центральное время данные API поступают правильно!

надеюсь, это поможет кому-то еще. Часовые пояса, амирит?

...