18

I've got a UIDatePicker in Time mode with an interval of 15 minutes.

Let's say it's 7:22PM. The value that the date picker shows per default is the current time rounded to the next higher/lower value, in this case, it's 7:15PM. If the user interacts with the date picker, the value that's shown is also the value returned. However if there hasn't been any user interaction and I get the time with [UIDatePicker date] the return value is the exact current time, i.e. 7:22 to stick with the example.

Is there any way to always get the value that's actually shown on the date picker instead of the current unrounded time, even if the user hasn't explicitly picked a value?

I've already tried to set the picker manually with [UIDatePicker setDate:[NSDate date]] but that doesn't change the behavior.

pkamb
  • 33,281
  • 23
  • 160
  • 191
TigreFurry
  • 483
  • 5
  • 14
  • possible duplicate of: http://stackoverflow.com/questions/6948297/uidatepicker-odd-behavior-when-setting-minuteinterval – mja Sep 21 '11 at 19:30
  • 2
    The problem is that the date stored in a date picker does not match the displayed value until the picker value is changed by the user. This mandates that pre-interval-clamped dates be fed into the picker otherwise the results will not be clamped if the user doesn't explicitly change the displayed value. The result is the output value will not be what the user expects since it is not what they see. I can understand why it wouldn't auto adjust (simplicty, as well as preserving other time components like seconds which might want to be masked from the user in some cases) but how do we force it? – ima747 Jan 26 '12 at 16:28

3 Answers3

20

I've modified @ima747 's answer for Swift 3/4 and as an extension of UIDatePicker. picker.clampedDate

extension UIDatePicker {
    /// Returns the date that reflects the displayed date clamped to the `minuteInterval` of the picker.
    /// - note: Adapted from [ima747's](http://stackoverflow.com/users/463183/ima747) answer on [Stack Overflow](http://stackoverflow.com/questions/7504060/uidatepicker-with-15m-interval-but-always-exact-time-as-return-value/42263214#42263214})
    public var clampedDate: Date {
        let referenceTimeInterval = self.date.timeIntervalSinceReferenceDate
        let remainingSeconds = referenceTimeInterval.truncatingRemainder(dividingBy: TimeInterval(minuteInterval*60))
        let timeRoundedToInterval = referenceTimeInterval - remainingSeconds
        return Date(timeIntervalSinceReferenceDate: timeRoundedToInterval)
    }
}
aasatt
  • 600
  • 3
  • 16
12

This isn't a perfect solution but it works for me. I've taken it from another post and modified it to accept different values.

- (NSDate*)clampDate:(NSDate *)dt toMinutes:(int)minutes {
    int referenceTimeInterval = (int)[dt timeIntervalSinceReferenceDate];
    int remainingSeconds = referenceTimeInterval % (minutes*60);
    int timeRoundedTo5Minutes = referenceTimeInterval - remainingSeconds; 
    if(remainingSeconds>((minutes*60)/2)) {/// round up
        timeRoundedTo5Minutes = referenceTimeInterval +((minutes*60)-remainingSeconds);            
    }
    return [NSDate dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)timeRoundedTo5Minutes];
}

Feed it an input date and a minute value (taken from the UIDatePicker.minuteInterval in the case of this thread) and it will return a time clamped to that interval which you can feed to the picker.

pkamb
  • 33,281
  • 23
  • 160
  • 191
ima747
  • 4,667
  • 3
  • 36
  • 46
0

@ima747 is right if I've changed date picker's default value then it's working fine and if I've read date from picker control without onChange then it's returning wrong date value.
But I've checked that, date picker control have set default date (current date and may be it use nearest time milliseconds) If I set it to custom date and also set time to any date and 1:00:AM so now my time picker always open with 1:00:AM instead of current time enter image description here

Bhavin Chauhan
  • 1,950
  • 1
  • 26
  • 47