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

Objective-C 日期時間處理完全指南:NSDate、NSDateFormatter、NSTimeInterval、時區轉換實戰

     編輯:關於C語言

核心類速覽

類職責關鍵屬性/方法
NSDate絕對時間點(參考日期:2001-01-01 00:00:00 UTC)`date`、`timeIntervalSince1970`、`timeIntervalSinceNow`、`dateByAddingTimeInterval:`
NSTimeInterval`typedef double`,以秒為單位的時間間隔正數=未來,負數=過去
NSDateFormatterNSDate ↔ NSString 雙向轉換`dateFormat`、`stringFromDate:`、`dateFromString:`、`timeZone`、`locale`
NSTimeZone時區資訊(偏移量、夏令時規則)`systemTimeZone`、`localTimeZone`、`secondsFromGMTForDate:`

NSDate 基礎操作

// 當前時間 (UTC)
NSDate *now = [NSDate date];
NSLog(@"UTC: %@", now);  // 輸出總是 UTC

// 獲取當前時區偏移秒數
NSTimeZone *tz = [NSTimeZone systemTimeZone];
NSInteger offset = [tz secondsFromGMTForDate:now];

// 本地時間 (UTC + 偏移)
NSDate *local = [NSDate dateWithTimeIntervalSinceNow:offset];
NSLog(@"本地: %@", local);

// 相對時間構建
NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:24*3600];
NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow:-24*3600];
NSDate *oneHourLater = [NSDate dateWithTimeIntervalSinceNow:3600];

// 時間間隔計算
NSTimeInterval diff = [tomorrow timeIntervalSinceDate:yesterday]; // 172800.0
NSTimeInterval since1970 = [now timeIntervalSince1970];           // Unix 時間戳

// 快速獲取本地時間 (一行代碼)
NSDate *localNow = [NSDate dateWithTimeIntervalSinceNow:[NSTimeZone localTimeZone].secondsFromGMT];

NSDateFormatter 格式化字符串規範

符號含義示例
`y`年`yyyy` → 2024
`M`月`MM` → 01, `MMM` → Jan
`d`日`dd` → 05
`H`時 (24制)`HH` → 14
`h`時 (12制)`hh` → 02
`a`AM/PM`a` → PM
`m`分`mm` → 05
`s`秒`ss` → 09
`z`時區名`z` → GMT+08:00
`E`星期`EEE` → Mon
`G`時代`G` → AD

雙向轉換實戰

NSDate → NSString

NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[fmt setTimeZone:[NSTimeZone systemTimeZone]];  // 關鍵:指定輸出時區
[fmt setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; // 避免 24/12 制歧義

NSString *str = [fmt stringFromDate:[NSDate date]];
NSLog(@"格式化: %@", str);  // 2024-01-15 14:30:05

NSString → NSDate

NSString *input = @"2024-01-15 14:30:05";
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[fmt setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; // 輸入視為 UTC
NSDate *date = [fmt dateFromString:input];

// 若輸入為本地時間字符串,需手動加上時區偏移
NSDate *localDate = [date dateByAddingTimeInterval:[NSTimeZone localTimeZone].secondsFromGMT];

練習:中文自定義格式

NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"yyyy年MM月dd日 HH點mm分ss秒"];
NSString *chinese = @"2024年01月15日 14點30分05秒";
NSDate *date = [fmt dateFromString:chinese];
// 再轉為本地時間
date = [date dateByAddingTimeInterval:[NSTimeZone localTimeZone].secondsFromGMT];

常見坑點與最佳實踐

坑點現象修正
NSDate 輸出總是 UTC`NSLog(@"%@", date)` 顯示 2024-01-15 06:30:00 +0000這是正常的!`description` 固定 UTC。用 `NSDateFormatter` 指定時區輸出
格式化器不指定時區同一代碼在不同手機輸出不一致**始終** `[fmt setTimeZone:...]`,通常用 `systemTimeZone` 或 `timeZoneWithAbbreviation:@"UTC"`
12/24 制歧義`hh` 配合 `a` (AM/PM) 使用;單用 `hh` 易混淆統一用 `HH` (24制) 或 明確設置 `locale` 為 `en_US_POSIX`
解析失敗返回 nil`dateFromString:` 返回 nil 無報錯檢查格式字符串完全匹配、時區正確、輸入字符串無隱形字符
頻繁創建 Formatter性能開銷大(解析格式字符串、創建內部緩存)**靜態單例復用** 或持有屬性復用,避免循環中創建
Unix 時間戳精度`timeIntervalSince1970` 返回 `double` 含毫秒需整秒傳給後端時:`(long long)[date timeIntervalSince1970]`

工程級封裝建議

// DateUtils.h
@interface DateUtils : NSObject
+ (NSString *)stringFromDate:(NSDate *)date format:(NSString *)fmt timeZone:(NSTimeZone *)tz;
+ (NSDate *)dateFromString:(NSString *)str format:(NSString *)fmt timeZone:(NSTimeZone *)tz;
+ (NSDate *)localDateFromUTCString:(NSString *)str format:(NSString *)fmt;
+ (NSString *)utcStringFromLocalDate:(NSDate *)date format:(NSString *)fmt;
+ (NSTimeInterval)timeIntervalSince1970:(NSDate *)date;
@end

// 內部持有靜態 NSDateFormatter 字典按格式緩存,線程安全用 GCD 鎖

總結

  • NSDate = 絕對時間點 (UTC 參考),無時區概念
  • NSDateFormatter = 格式化引擎,**必須顯式設置時區**
  • NSTimeInterval = 秒級 `double`,支援負數、小數
  • 最佳實踐:Formatter 復用、時區顯式、Locale 固定 `en_US_POSIX`、UTC 存儲/傳輸、本地顯示轉換
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved