4
extension Formatter {
    static let iso8601: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.timeZone = TimeZone.init(identifier: "America/New_York")
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
        return formatter
    }()
}
extension Date {
    var iso8601: String {
        return Formatter.iso8601.string(from: self)
    }
}

extension String {
    var dateFromISO8601: Date? {
        return Formatter.iso8601.date(from: self)   // "Mar 22, 2017, 10:22 AM"
    }
}



let dateFormat:String = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
let strDate: String = "2017-10-09T00:00:00.966Z"
if let dateFromString = strDate.dateFromISO8601
{
    print(dateFromString.iso8601)
}

Ok, so it does not do anything with the dateFormatter.date(from: sweDate)!) then? How can I get the string value to Date?

As per my knowledge Date doesn't store the time zone so it always prints the UTC time no matter what the time zone i have used upon formatting.

So what is the solution as i have to compare my local date with the converted date. which i cannot compare with the string. Any help is appreciated.

Jaydeep Vyas
  • 4,411
  • 1
  • 18
  • 44
  • "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" is wrong. By escaping the Z it won't consider the timezone in your date string. Z means UTC. if you escape the Z it will interprete your date string as local time and that's wrong – Leo Dabus Oct 10 '17 at 05:42
  • You can set a different timezone but it won't make a difference when parsing your date with the date format that contains the time zone also `"yyyy-MM-dd'T'HH:mm:ss.SSSZ"` check this https://stackoverflow.com/a/28016692/2303865. You can use the TimeZone to convert your date to string with a specific locale. – Leo Dabus Oct 10 '17 at 05:44
  • @LeoDabus i think there is no issue with Z even i escape Z it still output wrong date – Jaydeep Vyas Oct 10 '17 at 05:47
  • Don't escape it Z in your string means UTC. Same as +0000 Check the link I posted – Leo Dabus Oct 10 '17 at 05:47
  • So u mean to say i dont need to convert my string to utc "Z" indicates it already in utc right? – Jaydeep Vyas Oct 10 '17 at 05:49
  • yes Check also the image at that post that explains the time zone formats also – Leo Dabus Oct 10 '17 at 05:49
  • okey thanks after discarding first date formatter it print output in utc not local which is perfect but what for the NEwyork timzone – Jaydeep Vyas Oct 10 '17 at 05:51
  • date formatter by default uses the current time zone If you just need to display it to the user you should use dateStyle and timeStyle that will display a localized representation of the date https://stackoverflow.com/questions/28332946/nsdateformatter-stringfromdatensdate-returns-empty-string/28347285?s=1|24.1707#28347285. When posting a date string to a server you always create the UTC string representation of the date. – Leo Dabus Oct 10 '17 at 05:57
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156316/discussion-between-jaydeep-vyas-and-leo-dabus). – Jaydeep Vyas Oct 10 '17 at 05:59
  • Apart from the issue take a look at [ISO8601DateFormatter](https://developer.apple.com/documentation/foundation/iso8601dateformatter) (iOS 10+, macOS 10.12+) – vadian Oct 10 '17 at 06:57

1 Answers1

4

You should use Calendar method dateComponents(in: TimeZone) to check the relative date components in a different time zone as follow:

let dateString = "2017-10-09T18:00:00.000Z"
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
let date = formatter.date(from: dateString)!  // "Oct 9, 2017 at 3:00 PM" in Brazil
                                              // "Oct 9, 2017 at 2:00 PM" in New York
let components = Calendar.current.dateComponents(in: TimeZone(identifier: "America/New_York")!, from: date)  //calendar: gregorian (fixed) timeZone: America/New_York (fixed) era: 1 year: 2017 month: 10 day: 9 hour: 14 minute: 0 second: 0 nanosecond: 0 weekday: 2 weekdayOrdinal: 2 quarter: 0 weekOfMonth: 2 weekOfYear: 41 yearForWeekOfYear: 2017 isLeapMonth: false

if 8..<16 ~= components.hour!  {
    print("store is open in NY").  // "store is open in NY\n"
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571