0

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 :)

ioskaveen
  • 196
  • 1
  • 4
  • 14
  • 1
    You need to update your question with relevant code. – rmaddy Sep 09 '16 at 05:22
  • @rmaddy what do you mean by relevant code? this is the one line that is setting the "age restriction" on the datePicker – ioskaveen Sep 09 '16 at 05:23
  • The code where you set the label would be a great start since that is where you are having your problem. – rmaddy Sep 09 '16 at 05:25
  • Possible duplicate of http://stackoverflow.com/questions/29407599/nsdateformatter-return-wrong-date-swift/29409739 – FredericP Sep 09 '16 at 05:25
  • @rmaddy the label just shows the datepicker's date that's it, if I comment out the line `datePicker.maximum = NSCalendar....` the label would show the correct date. – ioskaveen Sep 09 '16 at 05:29
  • It *is* relevant how you convert the picker's date (which is an NSDate) to the label text (which is a String). – Martin R Sep 09 '16 at 05:40
  • @MartinR ahhh I see now, well I have uploaded the complete code – ioskaveen Sep 09 '16 at 05:53

1 Answers1

2

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
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571