没有时区信息的 NSDate 和字符串

NSDate and string without timezone information

我正在解析网络服务返回的一些 XML。字符串:2015-12-24T12:00:00fromTimestamp 中找到,没有时区。 "geniuses"(我不是那个意思)在几分钟内将时区信息保存在 XML 中自己的字段中。所以 300 表示 GMT+05:00。

我已经阅读了很多关于 NSDate 和所有时区的东西,我知道 NSDate 不关心时区,那是 NSDateFormatter 的工作。

但是,为了 "convert" 没有时区的时间戳,以便 NSDate 中的值代表 GMT 时间,我将 GMT+05:00 添加到字符串中,使其变为 2015-12-24T12:00:00 +05:00。必须这样做吗?当您从字符串转换为日期时不添加时区 NSDate 认为该值是 GMT 时间?那是我不明白的部分。只转换没有时区信息的字符串是错误的,因为 NSDate 无法从 NSDate 中的值中减去 5 小时?那是对的吗?我很难解释。

设置日期格式器的时区可能更简单 明确地。示例(为简洁起见省略了错误检查):

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)

您的评估是正确的,您的解决方案是两种可能的解决方案之一。

要确保日期字符串正确转换为 NSDate,您可以执行以下两项操作之一:

  1. 您需要确保日期字符串包含时区信息,并且日期格式化程序的格式字符串包含时区的正确格式说明符。这就是你在问题中描述的内容。
  2. 保留日期字符串,不带时区信息。但是您根据从 XML.
  3. 获得的时区字段在日期格式化程序上设置了特定时区

任何一种方法都会给你正确的 NSDate.

更新:我的第二种方法显示在 Martin R 的回答中。

我发现将 Martin 的方法封装为字符串的扩展更方便 class。它还在其前面加上当前时间戳,并将文本写入调试器输出。

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