DateTime.Round extension method

Posted on March 12, 2008. Filed under: 3.5, ASP.NET, Extensions, LINQ | Tags: , , , , |

I recently needed to group by minutes (or seconds, or hours, or days) in a LINQ expression, and I found that there isn’t a round function built into the C# DateTime object. The following will round to the nearest second, minute, hour, or day. I stopped there because different months have different numbers of days (and I don’t need to group by months…) but it is easy enough to add months and years to the code.

Keep in mind that this doesn’t give you the current minute (or whatever) rather it gives you the closest minute (or whatever).


using System;

namespace MikeInMadison
{
    public static class Extensions
    {
        public static DateTime Round(this DateTime d, RoundTo rt)
        {
            DateTime dtRounded = new DateTime();

            switch (rt)
            {
                case RoundTo.Second:
                    dtRounded = new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second);
                    if (d.Millisecond >= 500) dtRounded = dtRounded.AddSeconds(1);
                    break;
                case RoundTo.Minute:
                    dtRounded = new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, 0);
                    if (d.Second >= 30) dtRounded = dtRounded.AddMinutes(1);
                    break;
                case RoundTo.Hour:
                    dtRounded = new DateTime(d.Year, d.Month, d.Day, d.Hour, 0, 0);
                    if (d.Minute >= 30) dtRounded = dtRounded.AddHours(1);
                    break;
                case RoundTo.Day:
                    dtRounded = new DateTime(d.Year, d.Month, d.Day, 0, 0, 0);
                    if (d.Hour >= 12) dtRounded = dtRounded.AddDays(1);
                    break;
            }

            return dtRounded;
        }

        public enum RoundTo
        {
            Second, Minute, Hour, Day
        }
    }
}

I’m using this extension method within LINQ to group RateItems by minutes. I’m getting the high, low, open, close, and begin time in a list of stock prices.

            var rates = from ri in RateItems
                        group ri by ri.Time.Round(Extensions.RoundTo.Hour) into g
                        select new
                        {
                            Time = g.First().Time.Round(Extensions.RoundTo.Hour),
                            High = g.Max(g2 => g2.Bid),
                            Low = g.Min(g2 => g2.Bid),
                            Open = g.First().Bid,
                            Close = g.Last().Bid
                        };
Read Full Post | Make a Comment ( 5 so far )

Liked it here?
Why not try sites on the blogroll...