ioskayn ioskayn - 2 months ago 13
iOS Question

Date picker shows a different date (1 day behined) from when picked

I have a UIDatePicker that is connected to a UILabel. I want the user to pick a birthday that is more than 18 years ago (age restriction). So I have this line to set the

maximumDate
value:

datePicker.maximumDate = NSCalendar.currentCalendar().dateByAddingUnit(.Year, value: -18, toDate: NSDate(), options: [])


This line however causes the picker to show a 1 day behind the selected date. for example if I choose
September 27, 1956
on the picker the label shows
September 26, 1956
I believe it has to do with
NSDate()
using a different timezone one that is behind my local timezone.

switch dequeueFrom[indexPath.row] {
case .Birthday:
if let pickedBday = pickedBday,
let bday = NSDate.dateFromISOString(pickedBday) {
(cell as! RegisterTextFieldCell).content(bday.longFormattedString())
}


// dateFromISOSString is declared in an extension.swift


class func dateFromComponents(components: NSDateComponents) -> NSDate? {
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
return calendar?.dateFromComponents(components)
}

class func dateFromString(string: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss-SSS"

if let stringDate = dateFormatter.dateFromString(string) {
return stringDate
} else {
return nil
}
}

func ISOStringFromDate() -> String {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"

return dateFormatter.stringFromDate(self).stringByAppendingString("Z")
}

class func dateFromISOString(string: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

if let stringDate = dateFormatter.dateFromString(string) {
return stringDate
} else {
return nil
}
}


Any help with how I can make NSDate() be my local timezone so this one day behind issue can go away? Any help is greatly appreciated :)

Answer

The problem is in your method ISOStringFromDate because you are getting the local time and manually adding the Z (Z means UTC) to the string. Try like this when creating your iso8601:

extension NSDate {
    var iso8601: String {
        let dateFormatter = NSDateFormatter()
        dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
        dateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
        return dateFormatter.stringFromDate(self)
    }
}

and your code should be:

pickedDate.iso8601  // to get your date iso8601 string
Comments