C# 按时间范围划分的Linq滤波器

C# 按时间范围划分的Linq滤波器,c#,linq,datetime,search,filter,C#,Linq,Datetime,Search,Filter,我正在尝试构建一个Linq查询,该查询每天过滤2次 首先,我需要在日期之间(即:2013年12月26日至2014年1月26日)进行筛选,在此搜索之后,结果可能会在时间之间进行筛选(即:19:00至7:00之间的记录) 我已尝试使用此查询,但它不起作用: orders = CurrentOrders.Where(o => o.ImportedOn >= dateFrom && o.ImportedOn <= dateTo); orders = orders.Whe

我正在尝试构建一个Linq查询,该查询每天过滤2次

首先,我需要在日期之间(即:2013年12月26日至2014年1月26日)进行筛选,在此搜索之后,结果可能会在时间之间进行筛选(即:19:00至7:00之间的记录)

我已尝试使用此查询,但它不起作用:

orders = CurrentOrders.Where(o => o.ImportedOn >= dateFrom && o.ImportedOn <= dateTo);
orders = orders.Where(o => o.ImportedOn.TimeOfDay >= tFrom && o.ImportedOn.TimeOfDay <= tTo);
orders=CurrentOrders.Where(o=>o.ImportedOn>=dateFrom&&o.ImportedOn.TimeOfDay>=tFrom&&o.ImportedOn.TimeOfDay o.ImportedOn.TimeOfDay>=tFrom&&o.ImportedOn.TimeOfDay o.ImportedOn.TimeOfDay>=tFrom&&o
仅返回一个时间。例如:

            DateTime t = DateTime.Now;
            System.Diagnostics.Debug.WriteLine(t.ToString());
            var t2 = t.TimeOfDay;
            System.Diagnostics.Debug.WriteLine(t2.ToString());
public async Task<List<MyModel>> GetFilteredResultByDateAndTime
  (DateTime startDate, DateTime endDate)
{
  var result = from mytable in _context.MyTable
               where
               mytable.DateField >= startDate.Date
               && mytable.DateField <= endDate.Date
               select new MyModel
               {
                 DateField = mytable.DateField.Date,
                 DateFieldTime = mytable.DateField,
                 // Other fields of the model
               };

  // Now you can filter the result by the time
  var filteredResult = from r in result
                       where 
                       r.DateFieldTime.TimeOfDay >= startDate.TimeOfDay
                       && r.DateFieldTime.TimeOfDay <= endDate.TimeOfDay
                       select r;
  return await filteredResult.ToListAsync();
}
返回:

02.06.2014 11:48:33
11:48:33.6671525

因此,您可以只比较日期,不需要一天的时间。

我认为您的查询不会在时间范围为晚上9点到凌晨4点的情况下给出结果。假设ImportedOn是晚上7点,您检查晚上7点是否小于晚上9点,这是可以的,同时检查晚上7点是否小于凌晨4点,这是错误的。我没有看到任何错误如果你只考虑时间而增加了一天,则会有所不同。添加日期不会改变时间

我的建议是,当时间从大于时间到(例如,晚上9点到凌晨4点)时,创建两个时间间隔

我为DateTime创建了一个扩展方法,这样我们就可以检查日期是否属于某个时间范围

public static bool IsInTimeRange(this DateTime obj, DateTime timeRangeFrom, DateTime timeRangeTo)
        {
            TimeSpan time = obj.TimeOfDay, t1From = timeRangeFrom.TimeOfDay, t1To = timeRangeTo.TimeOfDay;

            // if the time from is smaller than the time to, just filter by range
            if (t1From <= t1To)
            {
                return time >= t1From && time <= t1To;
            }

            // time from is greater than time to so two time intervals have to be created: one {timeFrom-12AM) and another one {12AM to timeTo}
            TimeSpan t2From = TimeSpan.MinValue, t2To = t1To;
            t1To = TimeSpan.MaxValue;

            return (time >= t1From && time <= t1To) || (time >= t2From && time <= t2To);
        }
公共静态bool IsInTimeRange(此DateTime对象、DateTime时间范围从、DateTime时间范围到)
{
TimeSpan time=obj.TimeOfDay,t1From=timeRangeFrom.TimeOfDay,t1To=timeRangeTo.TimeOfDay;
//如果时间从小于时间到,只需按范围过滤即可
如果(t1From=t1From&&time=t1From&&time=t2From&&time p.IsInTimeRange(timeFrom,timeTo));
//断言
Assert.IsFalse(datesInPeriod.Any(p=>p.Hour==2));
IsFalse(datesPeriod.Any(p=>p.Hour==9));
Assert.IsTrue(datesInPeriod.Any(p=>p.Hour==12));
Assert.IsTrue(datesInPeriod.Any(p=>p.Hour==15));
Assert.IsFalse(datesInPeriod.Any(p=>p.Hour==18));
Assert.IsFalse(datesInPeriod.Any(p=>p.Hour==23));
}
[测试方法]
public void TimeRangeFilter\u timeFrom\u大于\u timeTo()
{
//安排
列表日期=新列表()
{
DateTime.Today.AddHours(2),//凌晨2点
DateTime.Today.AddHours(9),//上午9点
DateTime.Today.AddHours(12),//12 PM
DateTime.Today.AddHours(15),//下午3点
DateTime.Today.AddHours(18),//下午6点
DateTime.Today.AddHours(23).AddMinutes(50),//晚上11:50
DateTime.Today,//0 AM
};
//间隔时间:晚上十时至凌晨四时
DateTime timeFrom=DateTime.Today.AddHours(22),timeTo=DateTime.Today.AddHours(4);
//表演
var datesInPeriod=日期。其中(p=>p.IsInTimeRange(timeFrom,timeTo));
//断言
Assert.IsTrue(datesInPeriod.Any(p=>p.Hour==2));
IsFalse(datesPeriod.Any(p=>p.Hour==9));
IsFalse(datesPeriod.Any(p=>p.Hour==12));
IsFalse(datesPeriod.Any(p=>p.Hour==15));
Assert.IsFalse(datesInPeriod.Any(p=>p.Hour==18));
Assert.IsTrue(datesInPeriod.Any(p=>p.Hour==23));
}

Linq to SQL:如何查询日期时间字段中的时间范围

如果要在表上选择两个DateTime值之间有DateTime字段(在本例中称为DateField)的记录,请指定:

DateFiled >= dateValue && DateFiled <= dateValue
datefield>=dateValue&&datefield=startDate.Date
&&mytable.DateField=startDate.TimeOfDay

&&r.DateFieldTime.TimeOfDay“它不工作”几乎没有给我们任何信息。从
到到的
t的值是什么?你有什么数据?结果是什么?你期望得到什么?这是LINQ到SQL、EF、LINQ到对象,还是其他什么?你使用的LINQ是什么味道?记住,像LINQ到实体这样的东西需要你的代码可以是一致的转换为由数据库执行的等效SQL。非常抱歉,我忘了提到当tFrom和tTo来自同一天(即:15:00和20:00之间)时查询工作正常。问题出现在这样的时间(即:19:00和7:00之间)时间移到第二天。设置此时间后,不会返回任何记录。
[TestMethod]
        public void TimeRangeFilter_timeFrom_is_smaller_than_timeTo()
        {
            // arrange
            List<DateTime> dates = new List<DateTime>() 
            {
                DateTime.Today.AddHours(2), // 2 AM
                DateTime.Today.AddHours(9), // 9 AM
                DateTime.Today.AddHours(12), // 12 PM
                DateTime.Today.AddHours(15), // 3 PM
                DateTime.Today.AddHours(18), // 6 PM
                DateTime.Today.AddHours(23).AddMinutes(50), // 11:50 PM
                DateTime.Today, // 0 AM
            };
            // interval: 10 AM to 4 PM
            DateTime timeFrom = DateTime.Today.AddHours(10), timeTo = DateTime.Today.AddHours(16);

            // act
            var datesInPeriod = dates.Where(p => p.IsInTimeRange(timeFrom, timeTo));

            // assert
            Assert.IsFalse(datesInPeriod.Any(p => p.Hour == 2));
            Assert.IsFalse(datesInPeriod.Any(p => p.Hour == 9));
            Assert.IsTrue(datesInPeriod.Any(p => p.Hour == 12));
            Assert.IsTrue(datesInPeriod.Any(p => p.Hour == 15));
            Assert.IsFalse(datesInPeriod.Any(p => p.Hour == 18));
            Assert.IsFalse(datesInPeriod.Any(p => p.Hour == 23));

        }

        [TestMethod]
        public void TimeRangeFilter_timeFrom_is_greater_than_timeTo()
        {
            // arrange
            List<DateTime> dates = new List<DateTime>() 
            {
                DateTime.Today.AddHours(2), // 2 AM
                DateTime.Today.AddHours(9), // 9 AM
                DateTime.Today.AddHours(12), // 12 PM
                DateTime.Today.AddHours(15), // 3 PM
                DateTime.Today.AddHours(18), // 6 PM
                DateTime.Today.AddHours(23).AddMinutes(50), // 11:50 PM
                DateTime.Today, // 0 AM
            };
            // interval: 10 PM to 4 AM
            DateTime timeFrom = DateTime.Today.AddHours(22), timeTo = DateTime.Today.AddHours(4);

            // act
            var datesInPeriod = dates.Where(p => p.IsInTimeRange(timeFrom, timeTo));

            // assert
            Assert.IsTrue(datesInPeriod.Any(p => p.Hour == 2));
            Assert.IsFalse(datesInPeriod.Any(p => p.Hour == 9));
            Assert.IsFalse(datesInPeriod.Any(p => p.Hour == 12));
            Assert.IsFalse(datesInPeriod.Any(p => p.Hour == 15));
            Assert.IsFalse(datesInPeriod.Any(p => p.Hour == 18));
            Assert.IsTrue(datesInPeriod.Any(p => p.Hour == 23));

        }
DateFiled >= dateValue && DateFiled <= dateValue
public async Task<List<MyModel>> GetFilteredResultByDateAndTime
  (DateTime startDate, DateTime endDate)
{
  var result = from mytable in _context.MyTable
               where
               mytable.DateField >= startDate.Date
               && mytable.DateField <= endDate.Date
               select new MyModel
               {
                 DateField = mytable.DateField.Date,
                 DateFieldTime = mytable.DateField,
                 // Other fields of the model
               };

  // Now you can filter the result by the time
  var filteredResult = from r in result
                       where 
                       r.DateFieldTime.TimeOfDay >= startDate.TimeOfDay
                       && r.DateFieldTime.TimeOfDay <= endDate.TimeOfDay
                       select r;
  return await filteredResult.ToListAsync();
}