简体   繁体   English

NSDate和字符串,不带时区信息

[英]NSDate and string without timezone information

I am parsing some XML that is returned by a web service. 我正在解析Web服务返回的一些XML。 The string: 2015-12-24T12:00:00 is found in the fromTimestamp with no timezone. fromTimestamp找到没有时区的字符串: 2015-12-24T12:00:00 The "geniuses" (I don't mean that) keeps the timezone information in a own field in the XML in minutes. “天才”(我并不是说)将时区信息在几分钟内保存在XML中的自己的字段中。 So 300 means GMT+05:00. 因此300表示格林尼治标准时间+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. 我已经阅读了很多有关NSDate和所有时区的信息,并且我知道NSDate不在乎时区,这就是NSDateFormatter工作。

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 . 但是,为了“转换”没有时区的时间戳,以便NSDate中的值表示格林尼治标准时间,我将GMT+05:00 05:00添加到字符串中,使其变为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? 从字符串转换为日期时,如果不添加时区, NSDate认为该值是GMT时间? 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 ? 仅转换没有该时区信息的字符串是错误的,因为NSDate无法从NSDate内部的值中减去5小时? Is that correct? 那是对的吗? I am having a hard time explaining it. 我很难解释。

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)

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: 为了确保将日期字符串正确转换为NSDate ,您可以执行以下两项操作之一:

  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. 但是,您可以根据从XML获得的时区字段在日期格式器上设置特定的时区。

Either approach will give you the proper NSDate . 两种方法NSDate以为您提供适当的NSDate

Update: My second approach is shown in the answer by Martin R. 更新:我的第二种方法显示在Martin R的答案中。

I found it more convenient to wrap Martin's approach as an extension of the String class. 我发现将Martin的方法包装为String类的扩展更为方便。 It also prepends it with current timestamp and writes text ta a debugger output. 它还为它加上当前时间戳,并向调试器输出中写入文本。

Swift 5: 斯威夫特5:

"Hello world".log()

2019-09-05 12:18:10 Hello world 2019-09-05 12:18:10你好世界

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM