iOS學習筆記37-時間和日期計算
阿新 • • 發佈:2017-08-10
htm chinese 區域 nsis ios geo 代號 keyword 轉換
一、時間和日期計算
我們在應用開發中,時常須要和時間打交道,比方獲取當前時間,獲取兩個時間點相隔的時間等等,在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;
/* 返回當前對象時間與當前client時間的相隔秒數 */
- (NSTimeInterval)timeIntervalSinceNow;
/* 返回當前對象時間與指定時間的相隔秒數 */
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate;
以下是使用實例:
/* 獲取當前client時間 */
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:[email protected]:%@",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(@"[email protected]",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;
/* 返回當前client的本地化信息。即使改動了本地化設定,這個對象也不會改變 */
+(instancetype)currentLocale;
/* 返回當前client的本地化信息,當每次改動本地化設定,事實上例化的對象會隨之改變 */
+(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];
//獲取client本地化信息,不可響應改動
NSLocale *curLocale = [NSLocale currentLocale];
//獲取client本地化信息,可動態響應改動
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經常使用創建方法:
/* 返回client的邏輯日歷,即使改動了系統日歷設定,這個對象也不會改變 */
+(instancetype)currentCalendar;
/* 返回client的邏輯日歷,改動了系統日歷設定。這個對象會隨之改變 */
+(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-24NSMinuteCalendarUnit
:分鐘單位。範圍為0-60
NSSecondCalendarUnit
:秒單位。範圍為0-60NSWeekCalendarUnit
:周單位。範圍為1-53NSWeekdayCalendarUnit
:星期單位。每周的7天。範圍為1-7NSWeekdayOrdinalCalendarUnit
:沒全然搞清楚NSQuarterCalendarUnit
:幾刻鐘,也就是15分鐘。範圍為1-4NSWeekOfMonthCalendarUnit
:月包括的周數。最多為6個周NSWeekOfYearCalendarUnit
:年包括的周數。最多為53個周
NSYearForWeekOfYearCalendarUnit
:沒全然搞清楚NSTimeZoneCalendarUnit
:沒全然搞清楚
以下是使用實例:
//獲取client邏輯日歷
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);
具體介紹能夠參考這裏。講得非常具體:wayne23的博客
假設有什麽問題能夠在下方評論區中提出。O(∩_∩)O哈!
iOS學習筆記37-時間和日期計算