首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Objective-C 日期時間處理:NSDate 與 NSDateFormatter 完全指南

     編輯:關於C++

NSDate 是 Objective-C 處理日期時間的核心類,表示絕對時間點(自 2001-01-01 00:00:00 UTC 起的秒數)。配合 NSDateFormatter 可實現格式化輸出與解析。本文系統介紹常用 API、時間間隔計算、時區處理及格式化最佳實踐。

核心概念

  • 參考日期:iOS/macOS 使用 2001-01-01 00:00:00 UTC(而非 Unix 1970)。
  • NSTimeInterval:typedef double,單位為秒,可表示亞秒精度。
  • 不可變性:NSDate 實例創建後不可修改。

常用構造方法

// 當前時間
NSDate *now = [NSDate date];           // 自動釋放
NSDate *now2 = [[NSDate alloc] init];  // 等價

// 指定時間間隔
NSTimeInterval secs = 24 * 60 * 60; // 1天
NSDate *yesterday = [[NSDate alloc] initWithTimeIntervalSinceNow:-secs];
NSDate *tomorrow = [NSDate dateWithTimeInterval:secs sinceDate:now];

// 從時間戳創建(Unix 1970 或 參考日期 2001)
NSDate *from1970 = [NSDate dateWithTimeIntervalSince1970:1234567890];
NSDate *from2001 = [NSDate dateWithTimeIntervalSinceReferenceDate:123456789.0];

// 遠過去/遠未來(比較用)
NSDate *distantPast = [NSDate distantPast];
NSDate *distantFuture = [NSDate distantFuture];

時間間隔計算

NSTimeInterval since1970 = [now timeIntervalSince1970];      // Unix 時間戳
NSTimeInterval since2001 = [now timeIntervalSinceReferenceDate]; // 參考日期戳
NSTimeInterval sinceNow = [now timeIntervalSinceNow];          // 負值,距現在的秒數
NSTimeInterval diff = [date1 timeIntervalSinceDate:date2];     // date1 - date2

日期比較

BOOL isEqual = [date1 isEqualToDate:date2];
NSComparisonResult cmp = [date1 compare:date2]; // NSOrderedAscending/Same/Descending

NSDate *earlier = [date1 earlierDate:date2]; // 較早者
NSDate *later = [date1 laterDate:date2];     // 較晚者

NSDateFormatter:格式化與解析

常用格式符號

符號含義示例
y年yyyy=2024, yy=24
M月MM=01, M=1, MMM=Jan, MMMM=January
d日dd=01, d=1
H時(24制)HH=00, H=0
h時(12制)hh=12, h=12
m分mm=05
s秒ss=09
S毫秒SSS=123
z時區名GMT+08:00
Z時區偏移+0800
aAM/PMAM
E星期E=Mon, EEEE=Monday

格式化輸出

NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"]; // 或 setLocalizedDateFormatFromTemplate:
[fmt setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Shanghai"]]; // 重要:指定時區
[fmt setLocale:[NSLocale localeWithIdentifier:@"zh_CN"]]; // 本地化月份/星期名

NSString *str = [fmt stringFromDate:now];
// 輸出:2024-01-15 14:30:45 +0800

字符串解析為日期

NSDate *parsed = [fmt dateFromString:@"2024-01-15 14:30:45 +0800"];
if (parsed) {
    // 解析成功
} else {
    // 格式不匹配
}

常用預設風格

[fmt setDateStyle:NSDateFormatterMediumStyle]; // 日期風格
[fmt setTimeStyle:NSDateFormatterShortStyle];   // 時間風格
// 無需 setDateFormat,自動適配用戶地區設置

時間戳字符串互轉

// 時間戳字符串 -> NSDate
NSString *tsStr = @"1234567890";
NSTimeInterval ts = [tsStr doubleValue];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:ts];

// NSDate -> 時間戳字符串
NSString *outStr = [@([date timeIntervalSince1970]) stringValue];

最佳實踐與避坑指南

  1. 重用 Formatter:NSDateFormatter 創建開銷大,應作為靜態/實例變量重用,不要在循環中創建。
  2. 顯式設置時區:默認使用系統時區,服務端/跨時區場景必須 setTimeZone:。
  3. 設置 Locale:解析/生成中文月份名需 zh_CN 或 zh_Hans_CN。
  4. 嚴格模式:iOS 10+ 支持 setLenient:NO 拒絕「2024-02-30」等非法日期。
  5. ISO8601:iOS 10+ 可用 ISO8601DateFormatter 處理標準格式(如 "2024-01-15T14:30:45Z"),性能更好。
  6. 線程安全:NSDateFormatter 非線程安全,多線程環境用 Thread-local 或加鎖。

總結

NSDate 表示時間點,NSDateFormatter 處理人類可讀格式。掌握「構造 → 間隔計算 → 比較 → 格式化/解析」完整鏈路,並遵循「重用、顯式時區、嚴格模式」三原則,即可應對絕大多數日期時間業務需求。

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