NSDate/NSCalendar

參考文檔

NSDate

1 . 時間全都用NSData處理
2 . 顯示時直接轉NSString即可顯示正確東八區時間
3 . 通過DatePicker獲取的時間是東八區,所以要先換成0時區,再轉時間戳。

#pragma mark - NSDate
   //打印date1顯示的是當前時間對應的0時區時間
    NSDate *date1 = [NSDate date];

    //前推兩天時間(0時區)
    NSDate *date2 = [[NSDate alloc]initWithTimeInterval:- (60 * 60 * 24 * 2) sinceDate:date1];
    //當前時間往后推24小時(0時區)
    NSDate *date3 = [date1 dateByAddingTimeInterval:60 * 60 *24 ];   

    //String(東8區) ---> Date(0時區)2016-08-22 17:28:03 +0000
    NSString *str = @"2016年08月23日 1時28分03秒";
    NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc]init];
    dateFormatter1.dateFormat = @"YYYY年MM月dd日 HH時mm分ss秒";
    NSDate *date = [dateFormatter1 dateFromString:str];

   //將轉換過來的時間是0時區的要手動加8小時,即可變成東八區的NSDate時間
    NSDate *strDate = [date dateByAddingTimeInterval:8 * 60 * 60];
    NSLog(@"=====%@",strDate);

    
    //Date(0時區)---> String(東八區)
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    dateFormatter.dateFormat = @"yyyy年MM月dd日 HH時mm分ss秒 Z";//時區
    NSString *dateStr = [dateFormatter stringFromDate:date];
    NSLog(@"%@",dateStr); 

   //字符串會自動變成正確時間:2016年08月23日 01時28分03秒 +0800
   //*******因為NSDate是0時區,NSString是東八區********//
 
時間差異
//顯示零時區時間,差8個小時
 NSDate *date = [NSDate date];
 NSLog(@"當前時間%@",date);//2016-08-24 14:16:47 +0000

//字符串打印自動正確時間
 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
 NSString *dateStr = [dateFormatter stringFromDate:date];
 NSLog(@"%@",dateStr);  //2016-08-24 22:16:47
北京時間
   /****以NSDate顯示當前時區時間就會有8小時差異****/

  //1.獲取當前時間 零時區的時間
    NSDate *date = [NSDate date];
    NSLog(@"當前零時區時間 %@", date);//得到的是0時區的時間

    //2.獲得本地時間 東八區 晚八個小時 以秒計時,
    NSDate *date1 = [NSDate dateWithTimeIntervalSinceNow:8 * 60 * 60];
    NSLog(@"今天此時的時間 %@",date1);

    //3.昨天此時的時間
    NSDate *yesterdayDate = [NSDate dateWithTimeIntervalSinceNow:(-24 + 8) * 60 * 60];
    NSLog(@"昨天此時的時間 %@",yesterdayDate);

    //4.明天此刻
    NSDate *tomorrowDate = [NSDate dateWithTimeInterval:24 * 60 * 60 sinceDate:date1];
    NSLog(@"明天此刻的時間 %@",tomorrowDate);
獲取時間戳
//時間戳一定要對應的是0時區的
//時間戳應該是10位的,13位代表計算了毫秒,截取前十位就可以
// 時間戳,即1970.1.1 00:00:00為標準,某個時間與它的秒數,且NSDate必須是0時區的
NSDate *date = [NSDate date];
NSTimeInterval timeIn = [date timeIntervalSince1970];
NSLog(@"1970年1月1日0時0分0秒至今相差 %.0f 秒", timeIn);
NSDateFormatter
G              公元AD
YYYY           完整年
YY             年后兩位
MM             月顯示 1-12
MMM            英文月份簡寫
dd             日2位數
d              日1-2位數
EEE            簡寫星期幾,如Sun
EEEE           星期幾全寫
aa             AM/PM
HH             24小時制
hh             12小時制
mm             分
ss             秒
S              毫秒

NSDatePicker

UIDatePicker 繼承自UIContro,只是對UIPickerView的封裝

 //高度216是固定的
    UIDatePicker *picker = [[UIDatePicker alloc]initWithFrame:CGRectMake(0, 0, 300, 216)];
    [self.view addSubview:picker];
    //選取模式
    picker.datePickerMode =UIDatePickerModeDateAndTime; //默認
    //UIDatePickerModeCountDownTimer  //倒計時hour,minute
    //UIDatePickerModeTime;           //AM/PM,Hour,minute
    //UIDatePickerModeDate;           //year,month,day
    //時間間隔
    picker.minuteInterval = 1;
    //日期范圍
    //轉到其它日期后會自動選擇最近的日期
    NSDate* minDate = [[NSDate alloc]initWithTimeIntervalSinceNow:-60 * 60 * 24 * 3 ];
    NSDate* maxDate = [[NSDate alloc]initWithTimeIntervalSinceNow:60 * 60 * 24 * 3];
    picker.minimumDate = minDate;
    picker.maximumDate = maxDate;
    //獲取日期
    //第1種方式
    NSDate *pickDate = picker.date;
    //第2種方式
    [picker addTarget:self action:@selector(goAction:) forControlEvents:UIControlEventValueChanged];

NSCalendar

Calendar新增的很多方法確實簡單省事,但好些方法都是iOS 8.0后的方法

基礎使用

  • (id)currentCalendar / + (id)autoupdatingCurrentCalendar

這兩個類方法都將返回當前客戶端的邏輯日歷,
區別在于:currentCalendar取得的值會一直保持在cache中,第一次用此方法實例化對象后,即使修改了系統日歷設定,這個對象也不會改變。而使用autoupdatingCurrentCalendar,當每次修改系統日歷設定,其實例化的對象也會隨之改變。

  • (id)initWithCalendarIdentifier:(NSString *)string
    根據提供的日歷標示符初始化
    NSGregorianCalendar -- 公歷
    NSBuddhistCalendar -- 佛教日歷
    NSChineseCalendar -- 中國農歷
    NSHebrewCalendar -- 希伯來日歷
    NSIslamicCalendar -- 伊斯蘭歷
    NSIslamicCivilCalendar -- 伊斯蘭教日歷
    NSJapaneseCalendar -- 日本日歷
    NSRepublicOfChinaCalendar -- 中華民國日歷(臺灣)
    NSPersianCalendar -- 波斯歷
    NSIndianCalendar -- 印度日歷
    NSISO8601Calendar -- ISO8601

  • (void)setFirstWeekday:(NSUInteger)weekday
    設置每周的第一天從星期幾開始,比如:1代表星期日開始,2代表星期一開始,以此類推。默認值是1

  • (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date
    獲取一個小的單位在一個大的單位里面的序數
    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 -- 星期單位。范圍為1-7
    NSQuarterCalendarUnit -- 幾刻鐘,就是15分鐘。范圍為1-4

    NSWeekOfMonthCalendarUnit -- 月包含的周數。最多為6個周
    NSWeekOfYearCalendarUnit -- 年包含的周數。最多為53個周

   NSCalendar *calendar = [NSCalendar currentCalendar];
    //以2001-1-1 0:0:0的偏移秒數來初始化
    NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:10];
    //[calendar setFirstWeekday:2];
    NSInteger count = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
    NSLog(@"%ld",count);

默認情況下第一個周有5天,如果將minimumDaysInFirstWeek設置為6天,則原本是第一周的1月1日--1月5日被劃分到了上一年,返回0;
而1月6日--1月12日升為第一周,1月13日--1月19日升為第二周。。依此類推。
所以需要關注的是minimumDaysInFirstWeek與實際第一周包含天數的大小比較,如果提供的minimumDaysInFirstWeek比實際第一周的天數小,則一切不變;否則統計"一年中第幾周"、"一個月中第幾周"會產生變化。

    NSDateComponents *compt = [[NSDateComponents alloc] init];
    [compt setYear:2013];
    [compt setMonth:1];
    [compt setDay:20];
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDate *date = [calendar dateFromComponents:compt];
    
    //[calendar setMinimumDaysInFirstWeek:6];
    NSInteger count = [calendar ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitYear forDate:date];
    NSLog(@"%ld",count);

A .取得一個NSDate對象的1個或多個部分
-(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)date

#pragma mark - NSCalendar
    //初始化創建日歷
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSCalendarUnit unit =  NSCalendarUnitDay |
                         NSCalendarUnitMonth |
                          NSCalendarUnitYear |
                        NSCalendarUnitWeekday;
    
    //獲取時間相應日期
    NSDateComponents *components1 = [calendar components:unit fromDate:date1];
    NSDateComponents *components2 = [calendar components:unit fromDate:date2];

    //周日weekday=1,周六weekday=7
    NSLog(@"weekday--%ld,weekday--%ld",components1.weekday,components2.weekday);
    NSLog(@"day---%ld,day---%ld,%ld,",components1.day,components2.day, components1.day - components2.day);
    
    //返回兩個時間的差值組件,option暫時沒意義設為0
    NSDateComponents *components3 = [calendar components:unit
                                                fromDate:date2
                                                  toDate:date1
                                                 options:0];
    NSDateComponents *components4 = [calendar components:unit
                                      fromDateComponents:components2
                                        toDateComponents:components1
                                                 options:0];
    NSLog(@"%ld,%ld",components3.day ,components4.day);
    
    //是否當天日期
    NSLog(@"是否是今天--%d",[calendar isDateInToday:date1]);
    //是否是明天
    NSLog(@"是否是明天--%d",[calendar isDateInTomorrow:date3]);
    //是否是昨天
    NSLog(@"是否是昨天%d",[calendar isDateInYesterday:date2]);
    //是否是周六/周末
    NSLog(@"是否是同日%d",[calendar isDateInWeekend:date2]);
    //是否同一天
    NSLog(@"是否是同一天--%d",[calendar isDate:date1 inSameDayAsDate:date2]);
    //是否在指定的同一單位內
    NSLog(@"是否是同一月--%d",[calendar isDate:date1 equalToDate:date2 toUnitGranularity:NSCalendarUnitMonth]);


    //蘋果官方不推薦使用week
    NSLog(@"week(該年第幾周):%i", dateComponents.week);
    NSLog(@"weekOfYear(該年第幾周):%i", dateComponents.weekOfYear);
    NSLog(@"weekOfMonth(該月第幾周):%i", dateComponents.weekOfMonth);

注意:

  • 需要注意的是,只有明確指定了unitFlags,NSDateComponents相應的那一部分才有值。

B . 取得兩個NSDate對象的時間間隔
-(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options : (NSUInteger)opts

// 先定義一個遵循某個歷法的日歷對象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

//根據兩個時間點,定義NSDateComponents對象,從而獲取這兩個時間點的時差
NSDateComponents *componets = [calendar components:NSCalendarUnitDay fromDate:[NSDate date] toDate:[NSDate dateWithTimeIntervalSinceNow:24 * 60 * 60 * 8] options:0];
NSLog(@"%ld",componets.day);

注意:

  1. 得到的NSDateComponents對象可能會包含負數。
    例如:
    當toDate比fromDate晚10秒,second部分返回10;
    當toDate比fromDate早10秒,second部分返回-10

  2. 當指定unitFlags返回多個部分時,相隔的時間由多個部分共同組成(而不是獨立去表示)。例如:上面的例子時間相差5小時1分15秒,如果指定只返回second部分,將得到18075秒;如果指定返回minute和second部分,將得到301分15秒;如果指定返回hour、minute和second,將得到5小時1分15秒

C .根據據NSDateComponents對象得到一個NSDate對象
-(NSDate *)dateFromComponents:(NSDateComponents *)comps

//先定義一個遵循某個歷法的日歷對象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

// 定義一個NSDateComponents對象,設置一個時間點
NSDateComponents *dateComponentsForDate = [[NSDateComponents alloc] init];
[dateComponentsForDate setDay:6];
[dateComponentsForDate setMonth:5];
[dateComponentsForDate setYear:2004];

//根據設置的dateComponentsForDate獲取歷法中與之對應的時間點
//這里的時分秒會使用NSDateComponents中規定的默認數值,一般為0或1。
NSDate *date = [greCalendar dateFromComponents: dateComponentsForDate];

//得到本地時間,避免時區問題
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger interval = [zone secondsFromGMTForDate:date];
NSDate *localeDate = [date dateByAddingTimeInterval:interval];

NSLog(@"%@",date);

D. 在參數date基礎上,增加一個NSDateComponents類型的時間增量
-(NSDate *)dateByAddingComponents:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts

// 定義一個NSDateComponents對象,設置一個時間段
NSDateComponents *dateComponentsAsTimeQantum = [[NSDateComponents alloc] init];
[dateComponentsAsTimeQantum setDay:6];

//在當前歷法下,獲取6天后的時間
NSDate *date = [greCalendar dateByAddingComponents:dateComponentsAsTimeQantum toDate:[NSDate date] options:0];

//得到本地時間,避免時區問題
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger interval = [zone secondsFromGMTForDate:date];
NSDate *localeDate = [date dateByAddingTimeInterval:interval];

NSLog(@"%@",date);
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容