9

For example:

2011-08-11 16:59 becomes 2011-08-11 16:30

Mark Rucker
  • 6,952
  • 4
  • 39
  • 65
Dinesh
  • 334
  • 1
  • 5
  • 14

7 Answers7

22
DateTime RoundDown(DateTime dt, TimeSpan d)
{
    return new DateTime((dt.Ticks / d.Ticks) * d.Ticks);
}

Example:

var dt1 = RoundDown(DateTime.Parse("2011-08-11 16:59"), TimeSpan.FromMinutes(30));
// dt1 == {11/08/2011 16:30:00}

var dt2 = RoundDown(DateTime.Parse("2011-08-11 17:00"), TimeSpan.FromMinutes(30));
// dt2 == {11/08/2011 17:00:00}

var dt3 = RoundDown(DateTime.Parse("2011-08-11 17:01"), TimeSpan.FromMinutes(30));
// dt3 == {11/08/2011 17:00:00}
dtb
  • 213,145
  • 36
  • 401
  • 431
  • Thanks! Do you see any rounding problems with this? I am trying to RoundDown to the nearest minute and am randomly getting two different answers for the same interval. – Legend May 20 '15 at 17:39
16

I would say something like that

var time = DateTime.Now;
var rounded = time.AddMinutes(
        time.Minute>30 ? -(time.Minute-30) : -time.Minute) 

And you could even do your own extension

public static class TimeHelper {
   public static DateTime RoundDown (this DateTime time)
   {
       return time.AddMinutes(
         time.Minute>30 ? -(time.Minute-30) : -time.Minute);
   }
}

EDIT

This function cut's also the seconds / milliseconds if necessary. Thanks for the hint.

public static DateTime RoundDown(this DateTime time)
{
    return time.Subtract(
        new TimeSpan(0, 0, time.Minute > 30 ? (time.Minute - 30) : time.Minute, 
            time.Second, time.Millisecond));
}
BitKFu
  • 3,649
  • 3
  • 28
  • 43
  • As written, 'Minutes' does not compile - there is no 'Minutes' property on the `DateTime` type. Changing to 'Minute' it compiles, but since the `Minute` property is an `int` the seconds will remain in the rounded result rather than truncating to the whole minute mark as the OP desires. – devgeezer Apr 11 '12 at 20:51
4

A more generic solution rounding to the nearest time span:


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

public static DateTime RoundDown(this DateTime dt, TimeSpan d)
{
    var delta = dt.Ticks % d.Ticks;
    return new DateTime(dt.Ticks - delta);
}

public static DateTime RoundToNearest(this DateTime dt, TimeSpan d)
{
    var delta = dt.Ticks % d.Ticks;
    bool roundUp = delta > d.Ticks / 2;

    return roundUp ? dt.RoundUp(d) : dt.RoundDown(d);
}

It would be used this way:

var date = new DateTime(2010, 02, 05, 10, 35, 25, 450); // 2010/02/05 10:35:25
var rounded = date.RoundToNearest(TimeSpan.FromMinutes(30)); // 2010/02/05 10:30:00

More in this response.

Community
  • 1
  • 1
redent84
  • 18,901
  • 4
  • 62
  • 85
2
DateTime newDateTime = new DateTime(oldDateTime.Year, oldDateTime.Month, oldDateTime.Day
  ,oldDateTime.Hour, (oldDateTime.Minute / 30) * 30, 0);
yamen
  • 15,390
  • 3
  • 42
  • 52
Servy
  • 202,030
  • 26
  • 332
  • 449
1

Exploiting some math

var input = DateTime.Now; // or however you get DateTime
var rounded = input.AddMinutes(-input.TimeOfDay.TotalMinutes % 30d);

Note that TimeOfDay is a TimeSpan and its TotalMinutes property is a double and that the modulus operator functions on doubles like follows:

47.51 % 30d == 17.51

16.2 % 30d == 16.2

768.7 % 30d == 18.7

You could change the 30d to any value you like other than zero. Changing to 15 rounds down to 15 minute intervals for instance. Changing from 30d to -30d, didn't change the results from the tests that I ran.

You could create a rounding extension method (providing this rounding method for all DateTime values):

public static class DateTimeExtensions
{
    public static DateTime Round(this DateTime self, double minutesInInterval)
    {
        if (minutesInInterval == 0d) throw new ArgumentOutOfRangeException("minutesInInterval");
        return self.AddMinutes(-self.TimeOfDay.TotalMinutes % minutesInInterval);
    }
}
Community
  • 1
  • 1
devgeezer
  • 4,159
  • 1
  • 20
  • 26
0

There is no such function available

You can refer to : How can I round up the time to the nearest X minutes?

IF needed you can create one yourself

DateTime RoundUp(DateTime dt, TimeSpan d)
{
   return new DateTime(((dt.Ticks - d.Ticks + 1) / d.Ticks) * d.Ticks + d.Ticks);
}

eg:

var dt1 = RoundUp(DateTime.Parse("2011-08-11 16:59"), TimeSpan.FromMinutes(30));
// dt1 == {11/08/2011 16:30:00}
Community
  • 1
  • 1
Thakur
  • 1,890
  • 5
  • 23
  • 33
0

Here's how I handled it. Below is the base method and an overload to round to the nearest 30 minutes:

public static DateTime RoundMinutes(this DateTime value)
{
    return RoundMinutes(value, 30);
}

public static DateTime RoundMinutes(this DateTime value, int roundMinutes)
{
    DateTime result = new DateTime(value.Ticks);

    int minutes = value.Minute;
    int hour = value.Hour;
    int minuteMod = minutes % roundMinutes;

    if (minuteMod <= (roundMinutes / 2))
    {
        result = result.AddMinutes(-minuteMod);
    }
    else
    {
        result = result.AddMinutes(roundMinutes - minuteMod);
    }

    return result;
}
Brad Moeller
  • 116
  • 1
  • 4