Thursday, 11 March 2010
Main Menu
Home
Blog
News
Software
Forums
Music
Email
Web Links
Blog Links
Musical Links
Nerdery Links
Other Neato Links
Syndicate
 
Round a DateTimePicker to 15 minute increments
User Rating: / 0
PoorBest 
.NET Programming
Written by WATYF on Friday, 23 January 2009 (1047 hits)
Category: .NET Programming

This should be a quick one. Here's the problem... I've got a DateTimePicker (actually, a very large amount of them) on a form, and I want to modify those DateTimePickers so that when a user highlights the "minute" portion and clicks up or down on the spinner, the minutes go up or down in 15 minute increments (instead of one minute increments). Now, the biggest challenge to this is that the separate controls of the DateTimePicker (up, down buttons, formatted textbox, etc) are not exposed in any way (thanks Microsoft!), so I have no way of figuring out if the user clicked up, or down, or entered the minute manually. Because of this, I can't (at least, I personally haven't figured out how to) create a "perfect" solution to this problem. So I settled for the next best thing... a solution that accounts for 90% of the time and that my users will be happy with...


First off, I'd like to point out that my solution involves simply using the ValueChanged event of the DateTimePicker. One could, of course, go all out and make their own custom DateTimePicker class and override the ValueChanged event and then create an "Increment" Property for the control, so that you could easily set an increment for the DateTimePicker, but my situation doesn't call for all that, and it would require more calculations (for variable increments other than 15), and since I'm in a hurry (and suck at math) I decided to go the "quick and dirty" route.

The main part is contained in the ValueChanged event, and then there's a helper Function (for rounding up). The RoundUp function is most likely not the most efficient way to do this (since, again, I suck at math), but I couldn't find a "Round in such and such an increment" anywhere online, so I had to make do. Anyway... the basic premise of the solution is that if the minute value is a 1, 16, 31, or 46, then they clicked "up", so we increment up to the next 15 minute increment. If the minute value is a 14, 29, 44,or 59, then they clicked "down", so we round down. If it's any other number, then it's something they manually entered, so we simply round the number up to the next 15 minute increment. I'm sure you can see the "flaw" in this imperfect solution. If they manually enter a 1, or 16, or 29 (or whatever), then it will think they clicked up/down, and might not round properly. For example, if it's 5:15, and they click down, then it will round it DOWN to 5:00. But if it's 5:15 and the manually enter 5:14, then you'd think it should round UP, but instead, it will "think" they clicked "down" and therefore round the minute down to 5:00. Anyway... it's not a huge flaw, and 99% of the users will never even notice, so it's perfectly fine for me.

So here's the code:

Private Sub dtpMyTime_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dtpMyTime.ValueChanged

            'If it's already an increment of 15, exit sub

            If (sender.Value.Minute = 0) Or (sender.Value.Minute = 15) Or (sender.Value.Minute = 30) Or (sender.Value.Minute = 45) Then Exit Sub

            'If it's a 1, 16, 31, or 46 (i.e. they clicked "up")...

            If sender.Value.Minute = 1 Or sender.Value.Minute = 16 Or sender.Value.Minute = 31 Or sender.Value.Minute = 46 Then

                  'Add 14 minutes to the value

                  sender.Value = DateAdd(DateInterval.Minute, 14, sender.Value)

            ElseIf sender.Value.Minute = 14 Or sender.Value.Minute = 29 Or sender.Value.Minute = 44 Or sender.Value.Minute = 59 Then

                  'Otheriwse, if it's a 14, 29, 44, or 59 (i.e. they clicked "down"), subtract 14 minutes from the value

                  '   You have to subtract 74 (instead of 14) if it's 59, to take it down one hour

                  If sender.Value.Minute = 59 Then sender.Value = DateAdd(DateInterval.Minute, -74, sender.Value) Else

            sender.Value = DateAdd(DateInterval.Minute, -14, sender.Value)

            Else 'Otherwise, if it's not one digit away from a 15 minute interval (i.e. they manually entered a number)

                  'Round the number up to the next 15 minute increment

                  sender.Value = New DateTime(sender.Value.Year, sender.Value.Month, sender.Value.Day, sender.Value.Hour, RoundUp(sender.Value.Minute), 0)

            End If

      End Sub

      Private Function RoundUp(ByVal iMin) As Integer

            Dim x As Integer

            For i As Integer = 1 To 15

                  x = iMin + i

                  If x = 15 Or x = 30 Or x = 45 Or x = 0 Then Return x

            Next

      End Function

 

WATYF

 

 
Next >

Comments

You must javascript enabled to use this form

 

© 2010 Musical Nerdery
Joomla! is Free Software released under the GNU/GPL License.