你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS學習筆記37-時間和日期計算

iOS學習筆記37-時間和日期計算

編輯:IOS開發綜合

一、時間和日期計算

我們在應用開發中,時常需要和時間打交道,比如獲取當前時間,獲取兩個時間點相隔的時間等等,在iOS開發中與時間相關的類有如下幾個:
1. NSDate:表示一個絕對的時間點
2. NSTimeZone:時區信息
3. NSLocale:本地化信息
4. NSDateComponents:一個封裝了具體年月日、時秒分、周、季度等的類
5. NSCalendar:日歷類,它提供了大部分的日期計算接口
6. NSDateFormatter:用來在日期和字符串之間轉換

二、NSDate時間點

NSDate存儲的是世界標准時(UTC),輸出時需要根據時區轉換為本地時間

NSDate常用初始化方法:
/* 獲取當前時間,alloc/init得到的時間也是當前時間 */
+ (instancetype)date;
/* 以當前時間為基准,獲取偏移秒數的時間 */
+ (instancetype)dateWithTimeIntervalSinceNow:(NSTimeInterval)seconds;
/* 以1970年1月1日為基准,獲取偏移秒數的時間 */
+ (instancetype)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds;
/* 以2001年1月1日為基准,獲取偏移秒數的時間 */
+ (instancetype)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)seconds;
/* 以指定時間點為基准,獲取偏移秒數的時間 */
+ (instancetype)dateWithTimeInterval:(NSTimeInterval)seconds 
                           sinceDate:(NSDate *)date;
/* 獲取一個極早的時間點,0001-12-30 00:00:00 +0000 */
+ (instancetype)distantPast;
/* 獲取一個極晚的時間點,4001-01-01 00:00:00 +0000 */
+ (instancetype)distantFuture;
除了最後的2個獲取極早極晚時間的方法,其他方法都有對應的init前綴方法。 極早和極晚時間常用於定時器的開始和暫停 偏移秒數為正,表示比基准時間晚的時間,偏移秒數為負,表示比基准時間早的時間
NSDate常用的對象方法:
/* 以當前NSDate對象為基准,獲取偏移指定秒數後得到的新NSDate對象 */
- (instancetype)dateByAddingTimeInterval:(NSTimeInterval)seconds;
#pragma mark - 比較2個時間
/* 比較2個NSDate對象,返回較早的那個NSDate時間點對象 */
- (NSDate *)earlierDate:(NSDate *)anotherDate;
/* 比較2個NSDate對象,返回較晚的那個NSDate時間點對象 */
- (NSDate *)laterDate:(NSDate *)anotherDate;
/* 比較2個NSDate對象,返回枚舉類型(相等、早於、晚於) */
- (NSComparisonResult)compare:(NSDate *)anotherDate;
#pragma mark - 獲取相隔秒數,從參數時間開始,經過多少秒到達對象執行時間
/* 返回當前對象時間與1970年1月1日00:00:00的相隔秒數 */
- (NSTimeInterval)timeIntervalSince1970;
/* 返回當前對象時間與2001年1月1日00:00:00的相隔秒數 */
- (NSTimeInterval)timeIntervalSinceReferenceDate;
/* 返回當前對象時間與當前客戶端時間的相隔秒數 */
- (NSTimeInterval)timeIntervalSinceNow;
/* 返回當前對象時間與指定時間的相隔秒數 */
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate;
下面是使用實例:
/* 獲取當前客戶端時間 */
NSDate *date1 = [NSDate date];
/* 獲取比date1晚30秒的時間 */
NSDate *date2 = [NSDate dateWithTimeInterval:30 sinceDate:date1];
/* 比較2個時間,獲取較早的時間和較晚的時間 */
NSDate *earlierDate = [date1 earlierDate:date2];
NSDate *laterDate   = [date1 laterDate:date2];
NSLog(@"earlierDate:%@,laterDate:%@",earlierDate,laterDate);
/* 比較2個時間 */
NSComparisonResult result = [date1 compare:date2];
switch(result){
    case NSOrderedSame:
        NSLog(@"對象時間等於參數時間");
        break;
    case NSOrderedAscending:
        NSLog(@"對象時間早於參數時間");
        break;
    case NSOrderedDescending:
        NSLog(@"對象時間晚於參數時間");
        break;
}
/* 獲取相隔時間秒數,將返回結果-30,從date2的時間開始,倒退30秒到達date1的時間 */
NSTimeInterval seconds = [date1 timeIntervalSinceDate:date2];
NSLog(@"date1與date2相隔%@秒",seconds);

三、NSTimeZone時區

NSTimeZone常用初始化方法:
/* 根據時區名稱初始化,例如:America/Chicago(美國芝加哥) */
+ (instancetype)timeZoneWithName:(NSString *)aTimeZoneName;
/* 根據時區縮寫初始化,例如:EST(美國東部標准時間)、HKT(香港標准時間) */
+ (instancetype)timeZoneWithAbbreviation:(NSString *)abbreviation;
/* 返回系統時區 */
+ (NSTimeZone *)systemTimeZone;
/* 返回本地時區 */
+ (NSTimeZone *)localTimeZone;
時區名稱可以通過以下方法獲取:
/* 以數組形式返回所有已知的時區名稱 */
+(NSArray *)knownTimeZoneNames;
本地時區和系統時區的區別在於本地時區可以被修改,而系統時區不能修改
NSTimeZone常用對象方法:
/* 獲取時區名稱 */
- (NSString *)name;
/* 獲取時區縮寫 */
- (NSString *)abbreviation;
/* 獲取對象時區與零時區的間隔秒數 */
- (NSInteger)secondsFromGMT;

四、NSLocale本地化信息

NSLocale類返回本地化信息,主要體現在語言區域格式這兩個設置項。

NSLocale常用初始化方法:
/* 返回系統初始本地化信息 */
+(instancetype)systemLocale;
/* 返回當前客戶端的本地化信息,即使修改了本地化設定,這個對象也不會改變 */
+(instancetype)currentLocale;
/* 返回當前客戶端的本地化信息,當每次修改本地化設定,其實例化的對象會隨之改變 */
+(instancetype)autoupdatingCurrentLocale;
/* 用標示符初始化本地化信息,例如:en_US */
-(instancetype)initWithLocaleIdentifier:(NSString *)string;
NSLocale常用對象方法:
/* 根據不同的key返回各種本地化信息 */
- (id)objectForKey:(id)key;
/* 顯示特定地區代號下相應鍵的顯示名稱 */
- (NSString *)displayNameForKey:(id)key 
                          value:(id)value;
以下是使用實例:
//獲取系統本地化信息
NSLocale *sysLocale = [NSLocale systemLocale];
//獲取客戶端本地化信息,不可響應修改
NSLocale *curLocale = [NSLocale currentLocale];
//獲取客戶端本地化信息,可動態響應修改
NSLocale *autoCurLocale = [NSLocale autoupdatingCurrentLocale];
//通過標識創建自定義本地化信息
NSLocale *userLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
//獲取貨幣符號
NSString *strSymbol = [userLocale objectForKey:NSLocaleCurrencySymbol];
NSLog(@"貨幣符號:%@",strSymbol);//打印:¥
//獲取本地日歷
NSCalendar *calendar = [userLocale objectForKey:NSLocaleCalendar];
NSLog(@"本地日歷:%@",calendar);
//得到"en_US"的NSLocaleIdentifier鍵的顯示名稱
NSString *str = [userLocale displayNameForKey:NSLocaleIdentifier value:@"en_US"];
NSLog(@"標識顯示名稱:%@",str);//打印:英文(美國)

五、NSDateComponents時間封裝

NSDateComponents封裝了具體年月日、時秒分、周、季度等:

/* 創建一個日期對象 */
NSDateComponents*compt = [[NSDateComponents alloc] init];
[compt setEra:1];//紀元
[compt setYear:2013];//年
[compt setMonth:3];//月
[compt setDay:15];//日
[compt setHour:11];//小時
[compt setMinute:20];//分鐘
[compt setSecond:55];//秒鐘
[compt setQuarter:2];//幾刻鐘
[compt setTimeZone:[NSTimeZone systemTimeZone]];//時區
[compt setWeek:3];//一年的第幾周
[compt setWeekday:4];//周幾
[compt setWeekOfMonth:3];//一個月的第幾周
[compt setWeekOfYear:3];//一年的第幾周
[compt setCalendar:[NSCalendar currentCalendar]];//日歷

NSDateComponents通常不單獨使用,它經常與時間點NSDate、日歷類NSCalendar一起使用

六、NSCalendar日歷類

NSCalendar類,表示日歷,封裝了大量的計算日期方法

NSCalendar常用創建方法:
/* 返回客戶端的邏輯日歷,即使修改了系統日歷設定,這個對象也不會改變 */
+(instancetype)currentCalendar;
/* 返回客戶端的邏輯日歷,修改了系統日歷設定,這個對象會隨之改變 */
+(instancetype)autoupdatingCurrentCalendar;
/* 根據提供的日歷標示符初始化 */
-(instancetype)initWithCalendarIdentifier:(NSString *)string;
系統中定義的日歷標識符有:
NSGregorianCalendar:公歷 NSBuddhistCalendar:佛教日歷 NSChineseCalendar:中國農歷 NSHebrewCalendar:希伯來日歷 NSIslamicCalendar:伊斯蘭歷 NSIslamicCivilCalendar:伊斯蘭教日歷 NSJapaneseCalendar:日本日歷 NSRepublicOfChinaCalendar:中華民國日歷(台灣) NSPersianCalendar:波斯歷 NSIndianCalendar:印度日歷 NSISO8601Calendar:ISO8601日歷
NSCalendar常用的與NSDateComponents相關對象方法:
/* 
  取得一個NSDate對象的1個或多個部分轉為NSDateComponents,
  只有明確指定了unitFlags,NSDateComponents相應的那一部分才有值
 */
- (NSDateComponents *)components:(NSUInteger)unitFlags 
                        fromDate:(NSDate *)date;
/* 取得兩個NSDate對象的時間間隔,用NSDateComponents來封裝 */
- (NSDateComponents*)components:(NSUInteger)unitFlags 
                        fromDate:(NSDate*)startingDate 
                          toDate:(NSDate*)resultDate 
                         options:(NSUInteger)opts;/* 一般默認傳0即可 */
/* 根據NSDateComponents對象得到一個NSDate對象 */
- (NSDate*)dateFromComponents:(NSDateComponents*)comps;
/* 在參數date基礎上,增加一個NSDateComponents類型的時間增量 */
- (NSDate*)dateByAddingComponents:(NSDateComponents*)comps 
                            toDate:(NSDate*)date 
                           options:(NSUInteger)opts;/* 一般默認傳0即可 */

unitFlags參數通過下面的日歷單位NSCalendarUnit用或運算“|”組合使用

日歷單位NSCalendarUnit,可以用或運算“|”組合使用:
NSEraCalendarUnit
紀元單位。對於NSGregorianCalendar(公歷)來說,只有公元前(BC)和公元(AD);而對於其它歷法可能有很多,例如日本和歷是以每一代君王統治來做計算。 NSYearCalendarUnit:年單位。值很大,相當於經歷了多少年,未來多少年。 NSMonthCalendarUnit:月單位。范圍為1-12 NSDayCalendarUnit:天單位。范圍為1-31 NSHourCalendarUnit:小時單位。范圍為0-24 NSMinuteCalendarUnit:分鐘單位。范圍為0-60 NSSecondCalendarUnit:秒單位。范圍為0-60 NSWeekCalendarUnit:周單位。范圍為1-53 NSWeekdayCalendarUnit:星期單位,每周的7天。范圍為1-7 NSWeekdayOrdinalCalendarUnit:沒完全搞清楚 NSQuarterCalendarUnit:幾刻鐘,也就是15分鐘。范圍為1-4 NSWeekOfMonthCalendarUnit:月包含的周數。最多為6個周 NSWeekOfYearCalendarUnit:年包含的周數。最多為53個周 NSYearForWeekOfYearCalendarUnit:沒完全搞清楚 NSTimeZoneCalendarUnit:沒完全搞清楚
以下是使用實例:
//獲取客戶端邏輯日歷
NSCalendar *calendar = [NSCalendar currentCalendar];
//獲取當前時間
NSDate *date = [NSDate date];
//從date中讀取年月日,存儲在NSDateComponents對象中
NSDateComponents *compt1 = [calendar components:(NSYearCalendarUnit | 
                                                 NSMonthCalendarUnit | 
                                                 NSDayCalendarUnit) 
                                       fromDate:date];

NSLog(@"年:%d",[compt1 year]);//2016
NSLog(@"月:%d",[compt1 month]);//4
NSLog(@"日:%d",[compt1 day]);//19
/*********************************************************************/
//創建一個時間相差5小時1分15秒的時間點
NSDate *date2 = [NSDate dateWithTimeInterval:5*60*60+1*60+15 
                                   sinceDate:date];
//時間間隔NSDate轉NSDateComponents,分鐘加秒鐘
NSDateComponents *compt2 = [calendar components:(NSMinuteCalendarUnit | 
                                                 NSSecondCalendarUnit) 
                                       fromDate:date 
                                         toDate:date2 
                                        options:0];

NSLog(@"時間間隔【分種加秒鐘】:%d分%d秒",[compt2 minute],[compt2 second]);//301分15秒
//時間間隔NSDate轉NSDateComponents,只有秒鐘
NSDateComponents *compt3 = [calendar components:NSSecondCalendarUnit
                                       fromDate:date 
                                         toDate:date2 
                                        options:0];
NSLog(@"時間間隔【秒數】:%d秒",[compt3 second]);//18075秒
/*********************************************************************/
//創建自定義NSDateComponents對象
NSDateComponents *compt4 = [[NSDateComponents alloc] init];
[compt4 setYear:2012];
[compt4 setMonth:5];
[compt4 setDay:11];
//NSDateComponents對象轉NSDate對象
NSDate *newDate = [calendar dateFromComponents:compt4];
//得到本地時間,避免時區問題
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger interval = [zone secondsFromGMTForDate:newDate];
NSDate *localeDate = [newDate dateByAddingTimeInterval:interval];
NSLog(@"NSDateComponents對象轉NSDate對象:%@",localeDate);
/*********************************************************************/
//創建自定義NSDateComponents對象
NSDateComponents *compt5 = [[NSDateComponents alloc] init];
[compt5 setDay:25];
[compt5 setHour:4];
[compt5 setMinute:66];
NSDate *addDate = [calendar dateByAddingComponents:compt5 
                                            toDate:[NSDate date] 
                                           options:0];
//得到本地時間,避免時區問題
NSTimeZone *zone2 = [NSTimeZone systemTimeZone];
NSInteger interval2 = [zone2 secondsFromGMTForDate:addDate];
NSDate *localeDate2 = [addDate dateByAddingTimeInterval:interval2];
NSLog(@"NSDate對象追加NSDateComponents對象時間:%@",localeDate2);
NSCalendar類還有一些日歷設置和計算的方法:
/* 設置本地化信息 */
- (void)setLocale:(NSLocale *)locale;
/* 設置時區信息 */
- (void)setTimeZone:(NSTimeZone *)tz;
/* 設置每周的第一天是從星期幾開始,1表示是星期天(默認),2表示星期一,以此類推 */
- (void)setFirstWeekday:(NSUInteger)weekday;
/* 設置每年及每月第一周必須包含的最少天數,比如:設定第一周最少包括3天,則value傳入3 */
- (void)setMinimumDaysInFirstWeek:(NSUInteger)value;
/* 獲取一個小的單位在一個大的單位裡面的序數 */
- (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller 
                        inUnit:(NSCalendarUnit)larger 
                       forDate:(NSDate *)date;
/* 根據參數提供的時間點,得到一個小的單位在一個大的單位裡面的取值范圍 */
- (NSRange)rangeOfUnit:(NSCalendarUnit)smaller 
                inUnit:(NSCalendarUnit)larger 
               forDate:(NSDate *)date;
/* 
  根據參數提供的時間點,返回所在日歷單位的開始時間。
  如果startDate和interval都計算得出來,則返回YES;否則返回NO
 */
- (BOOL)rangeOfUnit:(NSCalendarUnit)unit  /* 日歷單位 */
          startDate:(NSDate **)datep /* 開始時間,通過參數返回 */
           interval:(NSTimeInterval *)tip /* 日歷單位所對應的秒數,通過參數返回 */
            forDate:(NSDate *)date; /* 時間點參數 */

七、NSDateFormatter字符串格式化

NSDateFormatter專門負責時間NSDate和字符串NSString之間的轉換

下面是格式化符使用規定:
大寫G:紀元
一般會顯示公元前(BC)和公元(AD) 小寫y:年
假如是2013年,那麼yyyy=2013,yy=13 大寫M:月
假如是3月,那麼M=3,MM=03,MMM=Mar,MMMM=March
假如是11月,那麼M=11,MM=11,MMM=Nov,MMMM=November 小寫w:年包含的周
假如是1月8日,那麼w=2(這一年的第二個周) 大寫W:月份包含的周(與日歷排列有關)
假如是2013年4月21日,那麼W=4(這個月的第四個周) 大寫F:月份包含的周(與日歷排列無關)
和上面的W不一樣,F只是單純以7天為一個單位來統計周,例如7號一定是第一個周,15號一定是第三個周,與日歷排列無關。 大寫D:年包含的天數
假如是1月20日,那麼D=20(這一年的第20天)
假如是2月25日,那麼D=31+25=56(這一年的第56天) 小寫d:月份包含的天數
假如是5號,那麼d=5,dd=05
假如是15號,那麼d=15,dd=15 大寫E:星期
假如是星期五,那麼E=Fri,EEEE=Friday 小寫a:上午(AM)/下午(PM) 大寫H:24小時制,顯示為0–23
假如是午夜00:40,那麼H=0:40,HH=00:40 小寫h:12小時制,顯示為1–12
假如是午夜00:40,那麼h=12:40 大寫K:12小時制,顯示為0–11
假如是午夜00:40,那麼K=0:40,KK=00:40 小寫k:24小時制,顯示為1–24
假如是午夜00:40,那麼k=24:40 小寫m:分鐘
假如是5分鐘,那麼m=5,mm=05
假如是45分鐘,那麼m=45,mm=45 小寫s:秒
假如是5秒鐘,那麼s=5,ss=05
假如是45秒鐘,那麼s=45,ss=45 大寫S:毫秒
一般用SSS來顯示 小寫z:時區
表現形式為GMT+08:00 大寫Z:時區
表現形式為+0800
下面是使用范例:
//創建日期字符串格式化器
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//設置時區
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
//設置格式化輸出格式
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
//創建時間
NSDateComponents *compt = [[NSDateComponents alloc] init];
[compt setYear:2013];
[compt setMonth:3];
[compt setDay:13];
[compt setHour:1];
[compt setMinute:55];
[compt setSecond:28];
//獲取日歷對象
NSCalendar *calendar = [NSCalendar currentCalendar];
//設置時區
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
//NSDateComponents對象轉NSDate對象
NSDate *date = [calendar dateFromComponents:compt];
NSLog(@"date:%@",date);
//格式化輸出字符串,傳入要格式化的時間NSDate對象
NSString *str = [formatter stringFromDate:date];
NSLog(@"格式化輸出:%@",str);
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved