使用 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) 會失敗。
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];
| 符號 | 含義 | 範例 | 適用制式 |
|---|---|---|---|
hh | 小時 (1-12) | 01, 12 | 12小時制 (需搭配 a) |
HH | 小時 (0-23) | 00, 13, 23 | 24小時制 |
a | AM/PM 標記 | AM, PM | 12小時制專用 |
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)
locale = en_US_POSIX:解析固定格式字串時,避免裝置設定干擾timeZone 設定為 UTC 或目標時區,避免隱性轉換