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

iOS NSDateFormatter 轉換含 AM/PM 字串:24小時制裝置相容性

     編輯:程式設計綜合問答

問題現象

使用 NSDateFormatter 轉換含 AM/PM 的日期字串,在裝置設為 **24小時制** 時回傳 nil。

錯誤代碼


NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"MM/dd/yyyy hh:mm:ss a"]; // 12小時制格式
NSString *aTime = @"2/11/2013 12:00:00 AM";
NSDate *aDate = [formatter dateFromString:aTime]; // 24小時制裝置回傳 nil

根本原因

NSDateFormatter 預設使用**裝置當前的 Locale 與 Calendar 設定**。當裝置為 24小時制時,解析器預期 24小時格式 (HH),遇到 12小時格式 (hh + a) 會失敗。

解決方案:強制設定 Locale 為 en_US_POSIX


NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 關鍵:固定 Locale,不受裝置設定影響
formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
formatter.dateFormat = @"MM/dd/yyyy hh:mm:ss a";

NSString *aTime = @"2/11/2013 12:00:00 AM";
NSDate *aDate = [formatter dateFromString:aTime]; // 現在任何裝置都能解析
NSLog(@"Date: %@", aDate);

完整最佳實踐模板


+ (NSDateFormatter *)fixedFormatter {
    static NSDateFormatter *formatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        formatter = [[NSDateFormatter alloc] init];
        formatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
        formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; // 或指定時區
        formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSZ"; // ISO 8601 範例
    });
    return formatter;
}

// 使用
NSDate *date = [self.class.fixedFormatter dateFromString:string];

格式符號對照:12小時制 vs 24小時制

符號含義範例適用制式
hh小時 (1-12)01, 1212小時制 (需搭配 a)
HH小時 (0-23)00, 13, 2324小時制
aAM/PM 標記AM, PM12小時制專用
mm分鐘 (0-59)05, 59通用
ss秒數 (0-59)00, 59通用

常見日期格式範例


// ISO 8601 (推薦 API 交換格式)
@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"  // 2023-12-25T14:30:00.000+0800
@"yyyy-MM-dd'T'HH:mm:ssZ"       // 2023-12-25T14:30:00+0800

// 常見顯示格式
@"yyyy/MM/dd HH:mm"             // 2023/12/25 14:30 (24小時)
@"MM/dd/yyyy hh:mm a"           // 12/25/2023 02:30 PM (12小時)
@"EEE, dd MMM yyyy HH:mm:ss z"  // Mon, 25 Dec 2023 14:30:00 GMT (RFC 1123)

關鍵原則

  1. 永遠設定 locale = en_US_POSIX:解析固定格式字串時,避免裝置設定干擾
  2. 重用 Formatter:建立成本高,用 static/dispatch_once 單例
  3. 明確時區:timeZone 設定為 UTC 或目標時區,避免隱性轉換
  4. 輸出格式另設:解析後要顯示給用戶時,再建立一個 Formatter 用裝置 Locale 格式化
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved