Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIDatePicker minus the exact time - Swift

I'm making an alarm clock where it will tell you how many hours and minutes of sleep you get. I set up a UIDatePicker where the user chooses what time they wanna wake up. It also tells the exact time to the very second. The part that I'm stuck on is how many hours of sleep they are going to get. I tried just basically subtracting the exact time from the UIDatePicker. This worked if they were both in the AM. For example if the user wanted to wake up at 10:30 AM and it is 9:30 AM all you have to do is subtract 10:30 from 9:30 to get 1 hour. I soon realized this wouldn't work if they were different time of days e.g. AM or PM.

How I got the time from UIDatePicker

func handler(sender: UIDatePicker) {
        var timeFormatter = NSDateFormatter()
        timeFormatter.timeStyle = NSDateFormatterStyle.ShortStyle

        var strDate = timeFormatter.stringFromDate(theDatePicker.date)


    }
theDatePicker.addTarget(self, action: Selector("handler:"), forControlEvents: UIControlEvents.ValueChanged)

How I got the exact time

var date = NSDate()
var outputFormat = NSDateFormatter()
outputFormat.locale = NSLocale(localeIdentifier:"en_US")
outputFormat.dateFormat = "HH:mm:ss"
timeLabel.text = (outputFormat.stringFromDate(date))
var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("getTime"), userInfo: nil, repeats: true)

My Question:

How do I subtract the UIDatePicker from the exact time to get the hours of sleep the user is getting?

theff

like image 474
alex Avatar asked Nov 09 '14 00:11

alex


2 Answers

You can use NSCalendar method components:fromDate:toDate:options:, for example:

@IBAction func valueChangedForPicker(sender: UIDatePicker) {
    let now = NSDate()
    let wakeUpTime = sender.date

    let calendar = NSCalendar.currentCalendar()
    let components = calendar.components(.HourCalendarUnit | .MinuteCalendarUnit | .SecondCalendarUnit, fromDate: now, toDate: wakeUpTime, options: nil)

    println(String(format: "%02d:%02d:%02d", components.hour, components.minute, components.second))
}

If you're getting negative values, that's because fromDate is not before toDate. In this case, if you're dealing with a NSDatePicker with time only, you might want to adjust the time of the wakeUpTime to make sure it is in the future.

var wakeUpTime = datePicker.date

if wakeUpTime.compare(now) == .OrderedAscending {
    wakeUpTime = calendar.dateByAddingUnit(.DayCalendarUnit, value: 1, toDate: wakeUpTime, options: nil)!
}
like image 152
Rob Avatar answered Nov 06 '22 20:11

Rob


Here is an example from a Swift playground:

// Setting up a date since I don't have a UIDatePicker
let dateString = "2014-11-12 07:25"
let dateFormatter: NSDateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm"

var wakeupTime: NSDate = dateFormatter.dateFromString(dateString)!
// var wakeupTime: NSDate = theDatePicker.date

let fromDate = NSDate()
let gregorianCalendar: NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
let flags: NSCalendarUnit = .HourCalendarUnit | .MinuteCalendarUnit

let components = gregorianCalendar.components(flags, fromDate: fromDate, toDate: wakeupTime, options: NSCalendarOptions(0))

println("\(components.hour) hours, \(components.minute) minutes")
like image 5
user212514 Avatar answered Nov 06 '22 20:11

user212514