首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS NSString 轉 NSDate 日期偏差一天?設定 TimeZone 為 GMT 解決

     編輯:程式設計綜合問答

問題現象


NSString *dateStr = @"7/25/2013 12:00:00 AM";
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"MM/dd/yyyy hh:mm:ss a"];
NSDate *date = [fmt dateFromString:dateStr];
NSLog(@"%@", date); // 輸出 2013-07-24 18:30:00 +0000 (少一天且時區偏移)

根本原因

NSDateFormatter 預設使用**裝置當前時區**解析無時區資訊的字串。若輸入字串為當地時間(如美東時間),而裝置在 UTC+8,解析出的 NSDate(內部儲存 UTC)會產生時差,導致日期顯示偏移。

解決方案:明確指定解析時區


[fmt setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; // 或 [NSTimeZone timeZoneWithName:@"GMT"]
// 解析後的 NSDate 即為正確的 UTC 瞬間

完整修正代碼


NSString *dateStr = @"7/25/2013 12:00:00 AM";
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"MM/dd/yyyy hh:mm:ss a"];
[fmt setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; // 關鍵行
NSDate *date = [fmt dateFromString:dateStr];
NSLog(@"dateStr: %@, date: %@", dateStr, date);
// 輸出: dateStr: 7/25/2013 12:00:00 AM, date: 2013-07-25 04:00:00 +0000 (正確 UTC)

Swift 版


let dateStr = "7/25/2013 12:00:00 AM"
let fmt = DateFormatter()
fmt.dateFormat = "MM/dd/yyyy hh:mm:ss a"
fmt.timeZone = TimeZone(secondsFromGMT: 0) // 或 TimeZone(abbreviation: "GMT")
if let date = fmt.date(from: dateStr) {
    print("date: \(date)") // 2013-07-25 04:00:00 +0000
}

進階:輸出顯示時再轉換回目標時區


// 解析時用 GMT,儲存 NSDate
// 顯示時轉換為用戶當地時區
let displayFormatter = DateFormatter()
displayFormatter.dateFormat = "yyyy-MM-dd HH:mm"
displayFormatter.timeZone = TimeZone.current // 或指定 TimeZone(identifier: "Asia/Taipei")
let displayStr = displayFormatter.string(from: date)

關鍵原則

  1. 解析無時區字串時,必須設定 timeZone,否則預設裝置時區導致偏移。
  2. 儲存/傳輸統一用 UTC (GMT),NSDate/Date 本身無時區概念,僅代表絕對時間點。
  3. 顯示時再套用目標時區,分離「解析/儲存」與「呈現」關注點。

加上 setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0] 即可徹底解決日期偏移問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved