LuckyLuke
LuckyLuke

Reputation: 49077

NSDate and string without timezone information

I am parsing some XML that is returned by a web service. The string: 2015-12-24T12:00:00 is found in the fromTimestamp with no timezone. The "geniuses" (I don't mean that) keeps the timezone information in a own field in the XML in minutes. So 300 means GMT+05:00.

I have been reading a lot about NSDate and all this timezone stuff and I know that NSDate don't care about timezones, thats NSDateFormatter job.

However, in order to "convert" the timestamp without the timezone so that the value in NSDate represents a GMT time I add the GMT+05:00 to the string so it becomes 2015-12-24T12:00:00 +05:00. This is how it must be done right? Without adding the timezone when you convert from string to date the NSDate thinks the value is the GMT time? Thats the part I don't understand about it. It would be wrong to just convert the string without that timezone information because NSDate wouldn't be able to subtract 5 hours from the value inside NSDate? Is that correct? I am having a hard time explaining it.

Upvotes: 0

Views: 1747

Answers (3)

vedrano
vedrano

Reputation: 2971

I found it more convenient to wrap Martin's approach as an extension of the String class. It also prepends it with current timestamp and writes text ta a debugger output.

Swift 5:

"Hello world".log()

2019-09-05 12:18:10 Hello world

extension String {

    func log() {

        let fmt = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd' 'HH:mm:ss"
        let formattedString = "\(fmt.string(from: Date())) \(self)"

        print(formattedString)

        let log = URL(fileURLWithPath: "log.txt")
        do {
            let handle = try FileHandle(forWritingTo: log)
            handle.seekToEndOfFile()
            handle.write((formattedString+"\n").data(using: .utf8)!)
            handle.closeFile()
        } catch {
            print(error.localizedDescription)
            do {
                try self.data(using: .utf8)?.write(to: log)
            } catch {
                print(error.localizedDescription)
            }
        }        
    }    
}

Upvotes: 0

rmaddy
rmaddy

Reputation: 318814

Your assessment is correct and your solution is one of two possible solutions.

To ensure the date string is properly converted to an NSDate, you can do one of two things:

  1. You need to ensure the date string has timezone information included and the date formatter's format string includes the proper format specifier for the timezone. This is what you describe in your question.
  2. You leave the date string as you have it, without timezone information. But you set a specific timezone on the date formatter based on the timezone field you get from the XML.

Either approach will give you the proper NSDate.

Update: My second approach is shown in the answer by Martin R.

Upvotes: 1

Martin R
Martin R

Reputation: 539755

It may be simpler to set the time zone of the date formatter explicitly. Example (error checking omitted for brevity):

let fromTimestamp = "2015-12-24T12:00:00"
let timeZoneInfo = "300"

let fmt = NSDateFormatter()
fmt.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

let secondsFromGMT = Int(timeZoneInfo)! * 60
fmt.timeZone = NSTimeZone(forSecondsFromGMT: secondsFromGMT)

let date = fmt.dateFromString(fromTimestamp)

Upvotes: 1

Related Questions