Thursday, July 12, 2007

Wow, so my last post had a glaring logic error.
It seems I forgot that the dateadd needed the conversion figure, r, not the modified version, c + r.
I've cleaned it up and added another function here so that I can still get the modified component with a function call.

Private Shared Function GetClosest15(ByVal t As Date)
Dim c As Int32 =
RoundTo15GetPlusMinusComponent(t.Minute)
Return DateAdd(DateInterval.Second,
-t.Second, DateAdd(DateInterval.Minute, c, t))
End Function


Private Shared
Function RoundTo15GetPlusMinusComponent(ByVal c As Int32)
Dim r As Int32 = c
Mod 15
If r <= 7 Then r *= -1 Else r = 15 - r
Return r
End
Function


Private Shared Function RoundTo15(ByVal c As Int32)
Dim r As
Int32 = RoundTo15GetPlusMinusComponent(c)
Return c + r
End Function

Rounding Time

One of the things that bothered me recently was trying to find the closest 15 minute time interval of a datetime.

I went through a few different scenarios before actually writing any code, but this one really did my head in.
For such as 'simple' operation, I found it difficult to identify the logic behind what I was trying to calculate.

Why would you want to do this I hear you ask?
Because sometimes, such as in this particular case (a timesheet entry) it is appropriate to round user input to the nearest component, to keep figures nice and tidy.

This code is in vb.net but it should be a fairly easy conversion.
If anyone can improve on it without using string manipulation, feel free to comment.

It's broken into two functions because another textbox on the same form accepts only minutes and needs to perform the same rounding.

Private Function GetClosest15(ByVal t As
Date)
Dim c As Int32 = RoundTo15(t.Minute)
Return
DateAdd(DateInterval.Second, -t.Second,
DateAdd(DateInterval.Minute, c, t))
End Function


Private Function RoundTo15(ByVal c As
Int32)
Dim r As Int32 = c Mod 15
If r <= 7 Then r *= -1
Else r = 15 - r
Return c + r
End Function