1

I'm trying to create a function that returns the period ending datetime for a timestamp, for a given resolution. For example if the resolution is 10 minutes (stored as a TimeSpan) and my timestamp is 2012-08-14 12:34 the period ending time would be 2012-08-14 12:40. Other examples below

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

I was trying to follow this article (written for t-sql) but was having trouble when it came to supporting resolutions of 15 minutes, 60 minutes and 1 day

Any idea how to make a dynamic solution that can support these multiple (and run time determined) resolutions?

EDIT This is what I have so far, it works as long as your resolution is less than 60 minutes, but as soon as your resolution is 1 hour you divide the minutes by zero and get an exception.

    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;
    }

2 Answers2

1

This answer works if your timespan is a factor of one day (864000000000 ticks).

Get the number of ticks in your timestamp and timespan. Take the modulus of the two, and this will give you the number of ticks so far inside the period. If this is zero then you may consider this to be the end of the previous period, and you are done. Otherwise, subtract that to give the start of the period, then add on the number of ticks in the timespan to give the end of the period.

Neil
  • 54,642
  • 8
  • 60
  • 72
0

Something like this? It uses an int, not a TimeSpan though...

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;
}

I have not thoroughly tested it though, but it can give you a start.

Vlad
  • 2,475
  • 21
  • 32