没有时区信息的 NSDate 和字符串
NSDate and string without timezone information
我正在解析网络服务返回的一些 XML。字符串:2015-12-24T12:00:00
在 fromTimestamp
中找到,没有时区。 "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
,您可以执行以下两项操作之一:
- 您需要确保日期字符串包含时区信息,并且日期格式化程序的格式字符串包含时区的正确格式说明符。这就是你在问题中描述的内容。
- 保留日期字符串,不带时区信息。但是您根据从 XML.
获得的时区字段在日期格式化程序上设置了特定时区
任何一种方法都会给你正确的 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)
}
}
}
}
我正在解析网络服务返回的一些 XML。字符串:2015-12-24T12:00:00
在 fromTimestamp
中找到,没有时区。 "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
,您可以执行以下两项操作之一:
- 您需要确保日期字符串包含时区信息,并且日期格式化程序的格式字符串包含时区的正确格式说明符。这就是你在问题中描述的内容。
- 保留日期字符串,不带时区信息。但是您根据从 XML. 获得的时区字段在日期格式化程序上设置了特定时区
任何一种方法都会给你正确的 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)
}
}
}
}