Как вычесть 1 день при использовании Datetime

Я пытаюсь получить количество заказов за последние 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

Есть еще один способ вычесть день из DateTime/DateTimeOffset stackoverflow.com/a/11152156/1043380

gunr2171 03.06.2024 19:12

Если вас не волнуют значения даты в разных часовых поясах, не используйте DateTimeOffset.

gunr2171 03.06.2024 19:14

Сторонняя система принимает только DateTimeOffSet. При использовании .AddDays это тоже не работает - i.Confirmed DateTime == datetime.AddDays(-1)

KeithViking 03.06.2024 19:16

«За последние 24 часа» и «За вчера» почти всегда означают разные вещи. Единственный момент, когда они совпадают, — это полночь любого дня. Было бы неплохо представить себе дату и время и числа с плавающей запятой, где дата — это целая часть, а время — десятичная часть. Это поможет вам мысленно смоделировать, почему дата-время 2024-02-03 12:34:56 не равно 2024-02-03 по тем же причинам, по которым 1,67485 не равно 1. Не используйте == при поиске чисел с плавающей запятой или дат в диапазоне. Используйте диапазоны, построенные на основе логики на основе > и <.

flackoverstow 04.06.2024 15:18

Например, «со вчерашнего дня» — это >= DateTime.Today.AddDays(-1) and < DateTIme.Today, т. е. две даты с интервалом в 24 часа, с полночью в качестве компонента времени, тогда как «за последние 24 часа» — это > DateTime.Now.AddDays(-1) and < DateTime.Now, т. е. две даты с интервалом в 24 часа с одинаковым компонентом времени. Свойство .Today дает текущую дату и время с временная часть установлена ​​на 00:00:00, что-то вроде операции «пол» уменьшит 1,67485 до 1

flackoverstow 04.06.2024 15:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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);

и вы обнаружите, что получили ожидаемый результат.

(Обратите внимание: хотя это и предназначено для ответа на ваш вопрос, это может быть не то поведение, которое вам нужно.)

Это сработало! Однако я не понимаю предупреждения, которое вы дали (о поведении)? Какое поведение может произойти, чего я не хочу?

KeithViking 03.06.2024 19:22

Привет, Кит! Все, что я имел в виду, это то, что в твоем вопросе говорится «за последние 24 часа», тогда как этот код получает все заказы за предыдущий день (что не совсем то же самое). Если это то, чего вы хотите, возможно, это нормально.

Neil T 03.06.2024 19:26

Чтобы поддержать «последние 24 часа», используйте > вместо == (и, конечно, сохраните компонент времени)

Fildor 03.06.2024 19:37

Другие вопросы по теме