-2

I'm trying to round a DateTime to the nearest 7 minute.

I've seen many rounding functions for c#, but for some reason, I'm getting different results to what I'm expecting.

Given the following time:

var d = new DateTime(2019, 04, 15, 9, 40, 1, 0);

If I want to round to the nearest 7th minute then I would expect the answer to be

2019-04-15 9:42:00     // 0, 7, 14, 21, 28, 35, 42 ?

Input / Expected result

new DateTime(2019, 04, 15, 9, 40, 0, 0);  // 9:42
new DateTime(2019, 04, 15, 9, 03, 0, 0);  // 9:07
new DateTime(2019, 04, 15, 9, 31, 0, 0);  // 9:35
new DateTime(2019, 04, 15, 9, 21, 0, 0);  // 9:21
new DateTime(2019, 04, 15, 9, 0, 0, 0);   // 9:00
new DateTime(2019, 04, 15, 9, 58, 0, 0);  // 10:00 (start again)

Various DateTime rounding functions that I've seen show the following answers, which I can't understand why unless I'm missing something

9:41 or
9:43

Example of rounding functions

public static DateTime RoundUp(this DateTime dt, TimeSpan d)
        {
            var modTicks = dt.Ticks % d.Ticks;
            var delta = modTicks != 0 ? d.Ticks - modTicks : 0;
            return new DateTime(dt.Ticks + delta, dt.Kind);
        }

DateTime RoundUp(DateTime dt, TimeSpan d)
{
    return new DateTime((dt.Ticks + d.Ticks - 1) / d.Ticks * d.Ticks, dt.Kind);
}
DotnetShadow
  • 748
  • 1
  • 10
  • 28
  • 3
    Please update your question to show at least 12 sample inputs and the expected results for each of those sample inputs. I am particularly interested in how 7 minutes works around the turn of the hour since 7 doesn't divide nicely into 60. So make sure your sample data includes data at the 57th, 58th and 59th minute. – mjwills Apr 18 '19 at 02:13
  • You are rounding to every 7 minutes based on the Ticks since the beginning of the DateTime era. So every single hour, day, and year, the answers will be different. – Tim Apr 18 '19 at 02:16
  • 1
    https://stackoverflow.com/questions/15154457/rounding-integers-to-nearest-multiple-of-10 seem to be exactly what you should want to compute correct minutes and than construct date back... but your sample code is way more complicated - so you may actually be looking for something else. – Alexei Levenkov Apr 18 '19 at 02:19
  • @AlexeiLevenkov I think the link you sent is more closer to what I'm looking for, thanks for that – DotnetShadow Apr 18 '19 at 03:03
  • @Tim good point, I understand this now I didn't realise how that would work – DotnetShadow Apr 18 '19 at 03:14

1 Answers1

1
static DateTime RoundUpNMinute(DateTime dt, int n)
{
    var minute = dt.Minute;
    if (minute % n == 0)
        return dt;

    var minuteRoundUp = minute / n * n + n;

    if(minuteRoundUp > 60)
        return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0, dt.Kind).AddHours(1);
    else
        return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, minuteRoundUp, 0, dt.Kind);
}

Got same results for all your examples.

shingo
  • 18,436
  • 5
  • 23
  • 42