0

I want to round datetime objects in C# to the nearest minute. So if the datetime object has 1 minute, 29 seconds and 999 miliseconds it should be rounded to 1 minute. If it has 1 minute, 30 seconds and 0 miliseconds, it should be rounded to 2 minutes.

I implemented this solution which I found from internet:

var timespan = new TimeSpan(0, 0, 1, 0);
//timespan has a value of 1 minute because I want to round to the nearest minute
return new DateTime(((dateTime.Ticks + timespan.Ticks/2)/ timespan.Ticks)* timespan.Ticks);

I'm not sure about the last line. Why do we divide by 2? Why do we divide with timespan.Ticks and then multiply?

petko_stankoski
  • 10,459
  • 41
  • 127
  • 231
  • 1
    Integer division truncates the decimal part. – Tim Schmelter Oct 13 '16 at 07:36
  • @TimSchmelter I assumed so, but is there a need for that in this case because 1 tick is 100 nanoseconds? – petko_stankoski Oct 13 '16 at 07:38
  • The ( + d.Ticks - 1) makes sure it will round up if necessary. The / and * are rounding. Example round 12 to the next 5: (12 + 5 - 1) = 16, 16 / 5 = 3 (because it is an integer datatype), 3 * 5 = 15. tada :) – Diego Frehner Aug 9 '14 at 10:13------ comments in http://stackoverflow.com/questions/7029353/how-can-i-round-up-the-time-to-the-nearest-x-minutes – Uthistran Selvaraj Oct 13 '16 at 07:38
  • 1
    @UthistranS. I saw that comment too but as you can see I dont have ( + d.Ticks - 1) in my solution, so that doesn't apply here. – petko_stankoski Oct 13 '16 at 07:41
  • 1
    value/base x base - rounds to the nearest base (greater or smaller than value), but (value+base/2)/base x base rounds to the nearest base which is greater than value – Leonid Malyshev Oct 13 '16 at 07:46
  • @LeonidMalyshev Thanks for the explanation. In my case since timespan.Ticks is always 600000000 do I have a need for (value+base/2)/base x base or can it become simpler? – petko_stankoski Oct 13 '16 at 08:09
  • in you case you don't want to round to the greater minute. So base/2 is not needed – Leonid Malyshev Oct 13 '16 at 08:14

1 Answers1

1

It's a lot used method of rounding to add half of desired precision and then cut the decimals. Examples:

  • Desired precision: 0.1 ( / 2 -> add 0.05 )

    1.44 + 0.05 = 1.49 -> cut last -> 1.4
    1.46 + 0.05 = 1.51 -> cut last -> 1.5
    
  • Desired precision: 0.01 ( / 2 -> add 0.005 )

    1.443 + 0.005 = 1.448 -> cut last -> 1.44
    1.465 + 0.005 = 1.470 -> cut last -> 1.47
    
  • Desired precision: 1minute -> add 0.5min or 30s or 30000 ticks* (assumed 1s = 1000 ticks). Unit doesn't matter as long as you keep units the same in all calculations.

    1min 25s + 30s = 1min 55s -> cut -> 1min
    1min 35s + 30s = 2min 05s -> cut -> 2min
    

So with datetime it's the same. In order to round by minute, you may add half a minute and then cut the rest away.

Ticks are one way of representing time. So just take the tick-count of a minute (new TimeSpan(0, 0, 1, 0)), divide it by two to get the half way and then add it to your time.

Now all you need to do is to cut the rest away and you can do it by diving your time with the precision (tick count of 1 minute). When you divide by 1 minute, everything that's smaller than a minute will be in decimals. Tick is an integer so it "forgets" all the decimals, thus cutting them away. Now all you need to do is make the value valid again by multiplying it with the same value you divided it with. Decimals are already lost at this point, so... TADAA: Rounded by minute.

Simo Erkinheimo
  • 1,347
  • 9
  • 17