Search code examples
swiftswift2nsdatensdateformatter

How to convert 2 Strings (date and time) into one NSDate object in Eastern Time Zone in Swift


I have the following code to convert a String with a date like April 22, 2017 and a second String with the time 4:30 PM and I need to convert these 2 Strings into one complete NSDate object in the Eastern Time Zone.

//convert scheduled date and time from String to NSDate
let scheduledServiceDateStr = orderReview.serviceDate //current format example: April 21, 2017
let scheduledServiceTimeStr = orderReview.serviceTime //current format example: 04:30 PM
print("scheduledServiceDateStr: \(scheduledServiceDateStr)")
print("scheduledServiceTimeStr: \(scheduledServiceTimeStr)")


let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMMM d, yyyy"
dateFormatter.timeZone = NSTimeZone(name: "EST")
let scheduledServiceDate = dateFormatter.dateFromString(scheduledServiceDateStr)
print("scheduledServiceDate: \(scheduledServiceDate)")

let timeFormatter = NSDateFormatter()
timeFormatter.dateFormat = "hh:mm a"
timeFormatter.timeZone = NSTimeZone(name: "EST")
let scheduledServiceTime = timeFormatter.dateFromString(scheduledServiceTimeStr)
print("scheduledServiceTime: \(scheduledServiceTime)")

let timeComponents = NSCalendar.currentCalendar().components([.Hour, .Minute, .Second], fromDate: scheduledServiceTime!)

let dateComponents = NSCalendar.currentCalendar().components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: scheduledServiceDate!)

// append the time to the date
dateComponents.hour = timeComponents.hour
dateComponents.minute = timeComponents.minute
dateComponents.second = timeComponents.second

let dateAndTime = NSCalendar.currentCalendar().dateFromComponents(dateComponents)
print("dateAndTime: \(dateAndTime)")

This is what is printed in the Console:

scheduledServiceDateStr: April 22, 2017
scheduledServiceTimeStr: 04:30 PM
scheduledServiceDate: Optional(2017-04-22 05:00:00 +0000)
scheduledServiceTime: Optional(2000-01-01 21:30:00 +0000)
dateAndTime: Optional(2017-04-21 20:30:00 +0000)

The issue I am having is that the ending result, the dateAndTime NSDate value displayed in the console at the end is 2017-04-21 20:30:00 +0000 but, the time 20:30:00 I believe is equivalent to 8:30 PM Eastern Time when the time originally selected was 4:30 PM. I understand that NSDate does not take Time Zones into account and that it is just a representation of of seconds since January 1, 2001. As you can see I am setting the Time Zone to EST before converting each String to an NSDate object. What am I doing wrong?


Solution

  • I don't think there's anything wrong with the time. EST is -04:00 so 16:30 EST = 20:30 GMT. And you wrote way more code that needed to be:

    let scheduledServiceDateStr = "April 21, 2017"
    let scheduledServiceTimeStr = "04:30 PM"
    
    let formatter = DateFormatter()
    formatter.dateFormat = "MMM dd, yyyy hh:mm a"
    formatter.timeZone = TimeZone(identifier: "EST")
    
    if let date = formatter.date(from: scheduledServiceDateStr + " " + scheduledServiceTimeStr) {
        print(date)
    }