如何找到最近的日期

时间:2016-05-20 10:03:09

标签: c# mysql sql-server lambda entity-framework-6

我的图表有三个精度。

每小时 每30分钟一次, 每15分钟一次。

我的数据表如下所示:

Data table

当我生成我的图表时,我从特殊日期时间开始,例如从当前日期时间开始

例如。当我从18:00开始,并且我的精确度是每15分钟我需要这个时间的数据

  • 18:00
  • 17:45
  • 17:30
  • 17:15
  • 17:00
  • ...

在我的数据表中,我每3分钟有一个数据最大值,所以当我想从17:15获取数据时,我的lambda查询返回null,因为我只有17:13和17:16的数据。

所以我需要查询whitch返回最接近数据时间的数据。在上面的示例中,需要从17:16返回数据。

我尝试使用DiffHours方法,但它不适用于MySQL。我需要处理MySQL和MSSQL的方法

我目前的方法如下:

var report = _reportRepository.FindBy(a => a.Fridge.FridgeIdentity == fridgeIdentity && a.CreatedDate.Year == fromTime.Year && a.CreatedDate.Month == fromTime.Month && a.CreatedDate.Day == fromTime.Day && a.CreatedDate.Hour == fromTime.Hour).FirstOrDefault();

但它仅适用于每小时精度。

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

如何获得最接近特定时间间隔的时间:

var fromTime = new DateTime(2016, 05, 20, 9, 0, 0);
var report = _reportRepository
             .OrderBy(m =>m.CreatedDate > fromTime 
                             ? m.CreatedDate - fromTime 
                             : fromTime - m.CreatedDate)
             .Take(1);

答案 1 :(得分:1)

你只展示了有限的代码,即使在几个问题之后也没有完全具体说明一些问题,所以我将假设以下内容:

  • 您可以为每小时精度创建一份工作报告,这意味着您可以生成所需时间的列表,例如18:00,18:15,18:30,间隔15分钟(你无法得到正确的数据),这些时间都在变量fromTime

  • 您的报告时间总是很长,例如18:00,从未17:48

  • 您最近的条目可以在查询时间之前和之后

  • 如果您这样做,例如一个15分钟的报告,并且数据库中没有值,日期时间在17:45:00到18:14:59之间,报告在18:00没有任何结果(因为您的数据每3分钟覆盖一次,所以无论如何都不应该成为问题,除了暂停)

您必须在3个间隔时间内使用不同的查询。使用15分钟(假设您的表名为a):

select *
from
(select *,
 convert(timestamp(date(date_add(CreatedDate, INTERVAL '7:30' MINUTE_SECOND)), 
         maketime(hour(date_add(CreatedDate, INTERVAL '7:30' MINUTE_SECOND)), 
         round(minute(date_add(CreatedDate, INTERVAL '7:30' MINUTE_SECOND)) div 15) 
          * 15, 0)), datetime) as filtertime
 from a
) as withfilter
order by filtertime, abs(timediff(filtertime, CreatedDate)) ;

对于其他间隔,您必须相应地更换间隔(因此将7:30替换为间隔时间的一半(以分钟为单位),将15替换为间隔时间(以分钟为单位),因此间隔时间为30分钟将是:

select *
from
(select *,
 convert(timestamp(date(date_add(CreatedDate, INTERVAL '15:00' MINUTE_SECOND)), 
         maketime(hour(date_add(CreatedDate, INTERVAL '15:00' MINUTE_SECOND)), 
         round(minute(date_add(CreatedDate, INTERVAL '15:00' MINUTE_SECOND)) div 30) 
          * 30, 0)), datetime) as filtertime
 from a
) as withfilter
order by filtertime, abs(timediff(filtertime, CreatedDate)) ;

(以及每小时间隔30:0060)。

这基本上将你的CreatedDate四舍五入到最接近的整个15/30/60分钟,然后按时间顺序对其进行排序。它将始终向上舍入,因此CreatedDate 2016-05-20 09:15:00将舍入到2016-05-20 09:30:00 30分钟,而不是2016-05-20 09:00:00

您可能希望直接查看结果以了解最终视图;对于您的示例数据,例如2016-05-20 09:18:40,它会首先计算3分钟15分钟,30分钟和1小时的过夜2016-05-20 09:15:002016-05-20 09:30:002016-05-20 09:00:00。然后根据它们到这些时间的距离(3:40分钟,11:20分钟和18:40分钟)命令它。

您的reportfilter必须使用filtertime而不是CreatedDate时间,您必须添加与fromtime进行比较的分钟数:

var report = _reportRepository.FindBy(a => a.Fridge.FridgeIdentity == fridgeIdentity 
   && a.filtertime.Year == fromTime.Year 
   && a.filtertime.Month == fromTime.Month 
   && a.filtertime.Day == fromTime.Day 
   && a.filtertime.Hour == fromTime.Hour
   && a.filtertime.Minute == fromTime.Minute).FirstOrDefault();