Использование ToString для объекта DateTime
В моей базе данных дата хранится как datetime, но когда я хочу выполнить поиск / фильтрацию, я хочу, чтобы она основывалась только на дате, игнорирующей точное время. Я трачу много времени на то, чтобы понять, как это сделать, и, наконец, я получил рабочее решение самостоятельно:
string val = rule.Data;
if (!string.IsNullOrEmpty(val))
{
switch (rule.Field)
{
case "Date": {
DateTime parsedDate = DateTime.ParseExact(
val,
"dd/MM/yyyy",
CultureInfo.InvariantCulture);
var pYear = parsedDate.Year;
var pMonth = parsedDate.Month;
var pDay = parsedDate.Day;
rows = rows.Where(o => o.Date >= parsedDate && o.Date <= new DateTime(pYear, pMonth, pDay, 12, 59, 40)); break;
}
}
}
Это работает хорошо. Это нужно немного изменить, но я думаю, что могу использовать код выше. Однако сегодня мой колледж передал мне решение, которое было взято из предыдущего проекта, разрабатываемого здесь, и это решение намного короче, и я бы предпочел использовать его, если это возможно. Это выглядит так:
string val = rule.Data;
if (!string.IsNullOrEmpty(val))
{
switch (rule.Field)
{
case "Date": { rows = rows.Where(o => o.Date.ToString("dd/MM/yyyy") == val); break; }
}
}
Код не ломается, когда я пытаюсь это сделать, но он также не фильтрует данные. Я всегда получаю пустой результат. я думаю что o.Date.ToString("dd/MM/yyyy")
в чем проблема. Я не знаю, нормально ли это использовать ToString()
как это для объекта DateTime. В примере я использую ToString()
также получите тип формата, подобный тому, который я предоставляю здесь - ToString("dd/MM/yyyy")
- но в моем случае ToString()
нигде не перегружен. Это стандартный способ манипулирования объектами DateTime, или я просто не могу найти место, где ToStrin()
является предопределенным И, наконец, не могли бы вы предоставить мне рабочий пример, основанный на приведенном выше коде.
3 ответа
В зависимости от культуры o.Date, попробуйте:
string val = rule.Data;
if (!string.IsNullOrEmpty(val))
{
switch (rule.Field)
{
case "Date":
{
rows = rows.Where(o => o.Date.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture) ==
DateTime.ParseExact(val,
"dd/MM/yyyy",
CultureInfo.InvariantCulture));
break;
}
}
}
Или вы можете установить культуру текущего потока вместо:
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
Редактировать: это должно работать, если вы избегаете использования строк:
например
DateTime maxDate = new DateTime(2020, 11, 17);
if (DateTime.Now.Date > maxDate)
{
// this will just work regardless of setting culture
}
Я думаю, что если вам нужно сравнить даты, то вы можете просто получить компонент Date в DateTime и сравнить его с вашим предопределенным значением. Это должно быть быстрее, так как не будет необходимости каждый раз преобразовывать дату в строку. Таким образом, вы можете сначала получить эталонное значение, как это DateTime.ParseExact(value, "dd/MM/yyyy", CultureInfo.InvarianCulture)
, Вы также можете просто использовать конструктор DateTime для его создания.
Вы не должны использовать строки вообще. Если это datetime
(или аналогичный) в базе данных, и DateTime
в вашем коде на C# нет веской причины использовать строку в качестве промежуточного шага.
Кроме того, вы должны обратить пристальное внимание на .Kind
собственность вашего DateTime
ценности. И вы никогда не должны сравнивать местное время с DateTime.Now
, В противном случае вы можете ввести ошибки при переходе на летнее время. Вместо этого вы должны использовать UTC DateTime
значения или использовать DateTimeOffset
значения вместо. Узнайте больше здесь.