tags:

views:

829

answers:

6

Hi, Does anyone have a good way to round down a number between 0 and 59 to the nearest 15. I'm using C# 3.5.

So ...

  • 1 would be 0
  • 29 would be 15
  • 30 would be 30

etc etc.

Many thanks.

+4  A: 

How about (x / 15) * 15?

No Refunds No Returns
You'll have to make sure that x is an integer type, first, however... (Or, at least, cast x / 15 to int)
Reed Copsey
As long as it's an int.
Mark Allen
+3  A: 

You can use integer division -

int number = 43;
int newNumber = number / 15;
int rounded = newNumber * 15;
Reed Copsey
gee ... I must be right.
No Refunds No Returns
@No Refunds No Returns: Only if x is an integer type...
Reed Copsey
A: 

As an extension method on the datetime

public static DateTime RoundDown(this DateTime dateTime)
{
    return new DateTime(dateTime.Year, dateTime.Month, 
         dateTime.Day, dateTime.Hour, (dateTime.Minute / 15) * 15, 0);
}

to use

DateTime date = dateTime.Now.RoundDown();//for example
johnc
Make sure to fit an abstract factory pattern in there somewhere for a more decoupled design.
Pierreten
Hey, I'm an extension method junkie. I offer no apology ;p
johnc
+4  A: 

x = x - (x % 15) would be a solution that doesn't rely on integer division.

Tanzelax
+1  A: 

I don't know of a library call for this (like .Round(...)), perhaps and extension method would fit nicely?

I would go for a simple IF statement.

If speed is an issue, try an expanded switch statement for each value. Use unit tests to see whats faster if that's an issue.

To be complete...

//...
[TestMethod]
    public void round_down()
    {
        Assert.AreEqual(-5.RoundDown(), 0);
        Assert.AreEqual(0.RoundDown(), 0);
        Assert.AreEqual(1.RoundDown(), 0);
        Assert.AreEqual(20.RoundDown(), 15);
        Assert.AreEqual(42.RoundDown(), 30);
        Assert.AreEqual(48.RoundDown(), 45);
        Assert.AreEqual(59.RoundDown(), 45);
        Assert.AreEqual(90.RoundDown(), 45);
    }

//...

public static class Ext
{
    public static int RoundDown(this int val)
    {
        if (val < 0)
            return 0;
        if (val < 15)
            return 0;
        if (val < 30)
            return 15;
        if (val < 45)
            return 30;
        return 45;
    }
}
Paul Kohler
He could also use a mocking framework to mock out the integer too for better testability (plus without all the overhead of integer allocation on the stack)
Pierreten
um no... the timing thing is because I assume that this is on a web site and there probably lots of it going on, that's all...
Paul Kohler
This gives the wrong answer for negative numbers.
Hightechrider
my assumption is that 0 is the lower boundary (59 the upper)
Paul Kohler
A: 

This is where the modulus operator comes in really handy

number - (number % 15)
Fadrian Sudaman