Using 24 Hour DatePicker in Swift

12,176

Solution 1

The OP says he is trying to recreate this answer in Swift. That answer is a kludge (it depends on Danish locale using 24-hour format, not on actually solving the problem), but here's how you would do that in Swift:

var datePicker = UIDatePicker() // Although you probably have an IBOutlet
datePicker.datePickerMode = UIDatePickerMode.Time
datePicker.locale = NSLocale(localeIdentifier: "da_DK")

but this is a kludge - roll your own UIPicker!

UPDATE The OP said that rolling your own is "hassle" - it's actually really easy - here's one simple way to do it (though a better way would be to subclass UIPickerView)...

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var myDatePicker: UIPickerView!
    private var calendar = Calendar.autoupdatingCurrent

    override func viewDidLoad() {
        super.viewDidLoad()
        self.time = Date() // updates the picker to "now"
    }

    // MARK: UIPickerViewDataSource
    func numberOfComponents(in: UIPickerView) -> Int { return 2 }
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if component == 0 { // Hours
            return 24
        }
        return 12 // five minute intervals
    }

    // MARK: UIPickerViewDelegate
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if component == 0 { // Hours
            return String(format: "%02d", row)
        }
        return String(format: "%02d", row * 5)
    }
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        print("picker changed, selected \(self.time)")
    }

    // MARK: Getting & setting the time
    var time: Date {
        get {
            let unitFlags: Calendar.Unit = [.year, .day, .hour, .minute, .second]
            var components = self.calendar.components(unitFlags, from: Date())
            components.hour = self.myDatePicker.selectedRow(inComponent: 0)
            components.minute = self.myDatePicker.selectedRow(inComponent: 1) * 5
            components.second = 0
            if let date = self.calendar.date(from: components) {
                return date
            }
            return Date() // shouldn't get here
        }
        set {
            var components = self.calendar.components([.hour, .minute], from: newValue)
            if let hour = components.hour, let minute = components.minute {
                self.myDatePicker.selectRow(hour, inComponent: 0, animated: true)
                self.myDatePicker.selectRow(minute / 5, inComponent: 1, animated: true)
            }
        }
    }
}

Solution 2

IOS Swift4

    let datePickerView: UIDatePicker = UIDatePicker()
    // For 12 hours Format
    datePickerView.locale = Locale(identifier: "en_US")
    // For 24 Hrs
    datePickerView.locale = Locale(identifier: "en_GB")
Share:
12,176
Prateek
Author by

Prateek

Updated on June 10, 2022

Comments

  • Prateek
    Prateek about 2 years

    I'm struggling to set the datepicker to only allow time and a 24 hour format in Swift, any ideas how to do this?

    Thanks

    • Grimxn
      Grimxn almost 10 years
      How would you have done it in Objective-C? What have you tried in Swift?
    • Prateek
      Prateek almost 10 years
      I have been using the method shown in this post stackoverflow.com/questions/2140388/… Not sure how to carry that to Swift
  • Prateek
    Prateek almost 10 years
    So how would I go about solving the problem and achieving a 24 hour format? Thanks for this by the way
  • Grimxn
    Grimxn almost 10 years
    As one of the answers in that other question said, by rolling your own UIPicker.
  • Prateek
    Prateek almost 10 years
    Hmm I see, but this workaround would not apply to all timezones? Won't the 24-hour format just be the same?
  • Grimxn
    Grimxn almost 10 years
    Yes, it will work (until Denmark adopt a different standard time format!)
  • Prateek
    Prateek almost 10 years
    Haha I should hope not! Great! And it would still work if the user has their phone set to 12 hour? I don't want to go to the hassle of creating a custom UIPickerView if this is doing the job I need?
  • Grimxn
    Grimxn almost 10 years
    Doing this will override the user locale settings for this control only. But it is this kind of kludge that caused so much heartache in Y2K!
  • Prateek
    Prateek almost 10 years
    In that case I should be safe for a while! Thanks!