我正在尝试创建一个函数,该函数返回给定分辨率的时间戳的句点结束日期时间。例如,如果分辨率为10分钟(存储为TimeSpan)且我的时间戳为2012-08-14 12:34,则截止时间段为2012-08-14 12:40。下面的其他例子
Timestamp: 2012-08-14 1:15; Resolution: 01:00:00; Result: 2012-08-14 2:00
Timestamp: 2012-08-14 11:59; Resolution: 00:10:00; Result: 2012-08-14 12:00
Timestamp: 2012-08-14 12:00; Resolution: 00:10:00; Result: 2012-08-14 12:00
Timestamp: 2012-08-14 12:01; Resolution: 00:10:00; Result: 2012-08-14 12:10
我试图关注this article(为t-sql编写),但在支持15分钟,60分钟和1天的分辨率方面遇到了麻烦
知道如何制作能够支持这些多个(和运行时确定的)分辨率的动态解决方案吗?
修改 这就是我到目前为止,只要您的分辨率小于60分钟,它就会起作用,但只要您的分辨率为1小时,您就将分钟除以零并获得例外。
public static DateTime ConvertToPeriodEndingTimestamp(TimeSpan resolution, DateTime timestamp)
{
var modifiedDate = new DateTime();
var baseDate = new DateTime(2008, 01, 01, 00, 00, 00);
var cursor = baseDate;
var nowToBaseDateDifference = timestamp.Subtract(baseDate).TotalMinutes;
//SET @Result = DATEADD(MINUTE, (resolution.TotalMinutes * (nowtoBaseDateDifference / resolution.TotalMinutes)) + resolution.TotalMinutes, '20000101')
modifiedDate =
baseDate.AddMinutes(((resolution.TotalMinutes*(int)(nowToBaseDateDifference/resolution.TotalMinutes)) +
resolution.TotalMinutes));
if(timestamp.Minute % resolution.Minutes == 0)
modifiedDate = modifiedDate.Add(-resolution);
return modifiedDate;
}
答案 0 :(得分:1)
如果您的时间跨度为一天(864000000000个刻度),则此答案有效。
获取时间戳和时间跨度中的滴答数。取两者的模数,这将给出期间内到目前为止的刻度数。如果这是零,那么你可以认为这是前一个时期的结束,你就完成了。否则,减去该值以给出期间的开始,然后在时间跨度中添加刻度数以给出期末。
答案 1 :(得分:0)
这样的东西?它使用的是int
,而不是TimeSpan
但是......
public static DateTime TimeRoundUp(DateTime dt, int Interval)
{
int nextMin = (int)(dt.Minute / Interval);
int lowerEdge = nextMin * Interval;
int upperEdge = lowerEdge + Interval;
if (dt.Minute - lowerEdge < upperEdge - dt.Minute)
{
nextMin = lowerEdge - dt.Minute;
}
else
{
nextMin = upperEdge - dt.Minute;
}
if (nextMin > 59)
{
nextMin = 60 - dt.Minute;
}
dt = dt.AddMinutes(nextMin);
dt = dt.AddSeconds(-dt.Second); // zero seconds
return dt;
}
我还没有彻底测试过它,但它可以给你一个开始。