Сравните только часть даты из DateTime, зная о смещении часового пояса в C#? - PullRequest
0 голосов
/ 13 марта 2020

Допустим, мне нужно отфильтровать записи по дате 2020-03-13 из следующих UT C Даты.

2020-03-13T11:40:37.552Z,
2020-03-13T13:40:37.552Z,
2020-03-13T19:40:37.552Z,
2020-03-13T21:40:37.552Z

Из предполагаемого клиента (со смещением часового пояса UTC+5) последние две записи произошли 2020-03-14 и только первые две записи должны быть возвращены. Как мне этого добиться? В настоящее время я делаю это как dbDate.Date == clientDate.Date для фильтрации записей, но он возвращает все записи.

Ответы [ 3 ]

2 голосов
/ 13 марта 2020

Рассмотрим два варианта:

  • Преобразуйте все даты в часовой пояс вашего клиента, затем сравните свойство Date каждого результата с 2020-03-13
  • Преобразовать начало 2020-03-13 и начало 2020-03-14 с часового пояса вашего клиента в UT C, а затем фильтрация на основе этого диапазона (с включающим началом и исключительным концом )

Последний потенциально более эффективен, использует только два преобразования - но он использует более сложный способ преобразования «локально в UT C» (где вам нужно беспокоиться о том, «что» случается, если полночь указанной даты не существует или происходит дважды из-за преобразований летнего времени) ... тогда как преобразование "конвертировать UT C в местное время" всегда однозначно.

Я бы, наверное, go для первого варианта, если эффективность не является существенной проблемой.

С точки зрения эффективности, обратите внимание, что если база данных хранит UT C, вы можете выполнить преобразования для второго варианта локально, а затем ge т база данных, чтобы сделать всю фильтрацию там. Я не знаю, насколько просто заставить базу данных фильтровать, включая преобразование из UT C в целевой часовой пояс. Если это сложно, вы можете, по крайней мере, выполнить некоторую фильтрацию в базе данных, предполагая, что смещение UT C пользователя никогда не будет превышать +/- 14 часов - так что вы можете получить все записи с помощью UT C значение в этом «максимально возможном окне» и затем sh локальная фильтрация путем преобразования каждого значения в код.

0 голосов
/ 13 марта 2020

Это в основном предложение Джона Скита в коде.

Сначала получите даты в объект DateTime в UT C. Затем перейдите в часовой пояс клиента и проверьте, соответствует ли дата вашим критериям.

var datesAsStrings = new string[]
{
  "2020-03-13T11:40:37.552Z",
  "2020-03-13T13:40:37.552Z",
  "2020-03-13T19:40:37.552Z",
  "2020-03-13T21:40:37.552Z"
};

foreach (var date in datesAsStrings)
{
  var utcDate = DateTime.Parse(date);
  var clientLocalTimeZoneDate = TimeZoneInfo.ConvertTime(utcDate, TimeZoneInfo.CreateCustomTimeZone("x", TimeSpan.FromHours(+5), "x", "x"));
  if (clientLocalTimeZoneDate.Date == new DateTime(2020, 3, 14))
  {
    Console.WriteLine(date);
  }
}

Вместо создания пользовательского часового пояса вы должны найти нужный вам, позвонив TimeZoneInfo.FindTimeZoneById с идентификатором часового пояса. вашего клиента.

0 голосов
/ 13 марта 2020

Если вы уже знаете часовой пояс клиента, преобразуйте дату и время клиента в UT C first

...