Я пытаюсь получить количество заказов за последние 24 часа из сторонней системы.
Раньше я не использовал DatetimeOffset, поэтому в конце концов понял, как вычесть 1 день из текущего дня. Затем я создал несколько фиктивных записей и установил для них значение вчерашнего дня, но с приведенным ниже кодом это, похоже, не работает (я ожидаю, что из 4-х поступят 3 ордера, поскольку их дата установлена на вчерашний день.
ordersTierAmount(DateTimeOffSet.UtcNow);
int ordersTierAmount(DateTimeOffset datetime)
{
var ts = new TimeSpan(1, 0, 0, 0);
var all = GetAll();
var count = all.Count(i => i.ConfirmedDateTime == datetime.Subtract(ts));
return count;
}
List<Order> GetAll()
{
return new List<Order>
{
new Order { Id = "1", ConfirmedDateTime = new DateTimeOffset(new DateTime(2024,06,02)) },
new Order { Id = "2", ConfirmedDateTime = new DateTimeOffset(new DateTime(2024,06,02)) },
new Order { Id = "3", ConfirmedDateTime = new DateTimeOffset(new DateTime(2024,06,02)) },
new Order { Id = "4", ConfirmedDateTime = new DateTimeOffset(new DateTime(2024,06,01)) }
};
}
public class Order
{
public string Id { get; set; }
public DateTimeOffset ConfirmedDateTime { get; set; }
}
Где я ошибаюсь? Что я упустил, чтобы не появилось нужное количество заказов?
Я прочитал MSDN и думаю, что сделал вычитание неправильно https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.subtract?view=net-8.0
Если вас не волнуют значения даты в разных часовых поясах, не используйте DateTimeOffset.
Сторонняя система принимает только DateTimeOffSet. При использовании .AddDays это тоже не работает - i.Confirmed DateTime == datetime.AddDays(-1)
«За последние 24 часа» и «За вчера» почти всегда означают разные вещи. Единственный момент, когда они совпадают, — это полночь любого дня. Было бы неплохо представить себе дату и время и числа с плавающей запятой, где дата — это целая часть, а время — десятичная часть. Это поможет вам мысленно смоделировать, почему дата-время 2024-02-03 12:34:56 не равно 2024-02-03 по тем же причинам, по которым 1,67485 не равно 1. Не используйте == при поиске чисел с плавающей запятой или дат в диапазоне. Используйте диапазоны, построенные на основе логики на основе > и <.
Например, «со вчерашнего дня» — это >= DateTime.Today.AddDays(-1) and < DateTIme.Today, т. е. две даты с интервалом в 24 часа, с полночью в качестве компонента времени, тогда как «за последние 24 часа» — это > DateTime.Now.AddDays(-1) and < DateTime.Now, т. е. две даты с интервалом в 24 часа с одинаковым компонентом времени. Свойство .Today дает текущую дату и время с временная часть установлена на 00:00:00, что-то вроде операции «пол» уменьшит 1,67485 до 1





Проблема в том, что DateTimeOffset, который вы передаете методу ordersTierAmount(), имеет ненулевой компонент Time, поэтому сравнение с фиктивными датами (которые не имеют компонента Time) вернет false.
Измените это:
var count = all.Count(i => i.ConfirmedDateTime == datetime.Subtract(ts));
к этому:
var count = all.Count(i => i.ConfirmedDateTime.Date == datetime.Subtract(ts).Date);
и вы обнаружите, что получили ожидаемый результат.
(Обратите внимание: хотя это и предназначено для ответа на ваш вопрос, это может быть не то поведение, которое вам нужно.)
Это сработало! Однако я не понимаю предупреждения, которое вы дали (о поведении)? Какое поведение может произойти, чего я не хочу?
Привет, Кит! Все, что я имел в виду, это то, что в твоем вопросе говорится «за последние 24 часа», тогда как этот код получает все заказы за предыдущий день (что не совсем то же самое). Если это то, чего вы хотите, возможно, это нормально.
Чтобы поддержать «последние 24 часа», используйте > вместо == (и, конечно, сохраните компонент времени)
Есть еще один способ вычесть день из DateTime/DateTimeOffset stackoverflow.com/a/11152156/1043380