如何找到最近的日期

4

我有三种精度的图表。

每小时,每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的数据。

因此,我需要查询最接近我的数据时间的数据。在上面的例子中,它需要返回来自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();

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

感谢您的帮助!


你需要能够从随机时间开始,还是始终是15分钟的倍数?例如,你的开始时间可以是18:03:45(然后你需要找到最接近的时间为18:18:45,以此类推),或者你总是从整点开始(18:00、18:15、18:30等)? - Solarflare
目标数据 - 我不知道它如何解决我的问题,你能给我写个例子吗? - Robson
Solarflare - 我总是从整数值开始。 - Robson
还有一个问题:您的工作报告代码只会给出整点之后的时间,因此如果您有17:59和18:03,它将为18:00给出18:03。您说您的报告对于整点工作正常。是这种情况吗?您不想包括过去的时间吗?这将使它变得更容易! - Solarflare
不行,因为数据来自我的设备,当有人触摸它们时,这个设备会发送报告 - 所以我无法控制这个。 - Robson
显示剩余4条评论
2个回答

5
如何获取最接近特定时间间隔的时间:
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
你只展示了有限的代码,并且在多次提问后仍然没有完全明确一些问题,因此我将做出以下假设:
  • 你能够创建一个精准到小时的工作报告,这意味着你能够生成所需时间的列表,例如每15分钟的时间,例如18:00、18:15、18:30(你只是无法获得正确的数据),并且这些时间在变量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,而不是 2016-05-20 09:00:00,对于 30 分钟的时间间隔。
你可能需要直接查看结果来理解最终视图;例如,对于你的示例数据2016-05-20 09:18:40,它将首先计算三个查询15分钟、30分钟和1小时的2016-05-20 09:15:002016-05-20 09:30:002016-05-20 09:00:00filtertimes。然后,它将按照它们到这些时间的距离进行排序(3:40min、11:20min和18:40min)。
你的报告过滤器将需要使用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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接