NSCalendar + NSDateComponents

NSDateComponents

若获取dateComponents对象时,设置components的时候未添加NSYearCalendarUnit,dateComponents.year将返回错误的数值,其他的也一样,所以使用NSDateComponents表示时间时,要确保需要使用的数据都在componets中添加了。

One

    // 定义一个遵循某个历法的日历对象 NSGregorianCalendar国际历法
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

    // 通过已定义的日历对象,获取某个时间点的NSDateComponents表示,并设置需要表示哪些信息(NSYearCalendarUnit, NSMonthCalendarUnit, NSDayCalendarUnit等)
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    NSInteger unitFlags = NSCalendarUnitEra |
    NSCalendarUnitYear |
    NSCalendarUnitMonth |
    NSCalendarUnitDay |
    NSCalendarUnitHour |
    NSCalendarUnitMinute |
    NSCalendarUnitSecond |
    NSCalendarUnitWeekday |
    NSCalendarUnitWeekdayOrdinal |
    NSCalendarUnitQuarter |
    NSCalendarUnitWeekOfMonth |
    NSCalendarUnitWeekOfYear |
    NSCalendarUnitYearForWeekOfYear |
    NSCalendarUnitNanosecond |
    NSCalendarUnitCalendar |
    NSCalendarUnitTimeZone;
    comps = [calendar components:unitFlags fromDate:[NSDate date]];
    
    NSLog(@"era(世纪): %li", (long)comps.era);
    NSLog(@"year(年份): %li", (long)comps.year);
    NSLog(@"quarter(季度):%li", (long)comps.quarter);
    NSLog(@"month(月份):%li", (long)comps.month);
    NSLog(@"day(日期):%li", (long)comps.day);
    NSLog(@"hour(小时):%li", (long)comps.hour);
    NSLog(@"minute(分钟):%li", (long)comps.minute);
    NSLog(@"second(秒):%li", (long)comps.second);
    
    //    Sunday:1, Monday:2, Tuesday:3, Wednesday:4, Thursday:5, Friday:6, Saturday:7
    NSLog(@"weekday(星期):%li", (long)comps.weekday);
    
    //    苹果官方不推荐使用week
    NSLog(@"week(该年第几周):%li", (long)comps.week);
    NSLog(@"weekOfYear(该年第几周):%li", (long)comps.weekOfYear);
    NSLog(@"weekOfMonth(该月第几周):%li", (long)comps.weekOfMonth);
    NSLog(@"yearForWeekOfYear(年):%li", (long)comps.yearForWeekOfYear);//不是很明白其含义

Two

// 先定义一个遵循某个历法的日历对象
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 *dateFromDateComponentsForDate = [greCalendar dateFromComponents:dc];

// 定义一个NSDateComponents对象,设置一个时间段
NSDateComponents *dateComponentsAsTimeQantum = [[NSDateComponents alloc] init];
[dateComponentsAsTimeQantum setDay:6];

// 在当前历法下,获取6天后的时间点
NSDate *dateFromDateComponentsAsTimeQantum = [greCalendar dateByAddingComponents:dateComponentsAsTimeQantum toDate:[NSDate date] options:0];

Three

// 先定义一个遵循某个历法的日历对象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

// 根据两个时间点,定义NSDateComponents对象,从而获取这两个时间点的时差
NSDateComponents *dateComponents = [greCalendar components:NSYearCalendarUnit fromDate:[NSDate dateWithTimeIntervalSince1970:0] toDate:[NSDate date] options:0];
NSLog(@"number of years:%li", (long)dateComponents.year);

NSCalendar中比较重要的方法和概念

firstWeekday

firstWeekday是大家比较容易浑淆的东西。
大家在使用dateComponents.weekday获取某天对应的星期时,会发现,星期日对应的值为1,星期一对应的值为2,星期二对应的值为3,依次递推,星期六对应的值为7,这与我们平时理解的方式不一样(歪果仁好像一周的开始就是周日,而不是周一)。然后,我们就开始找是不是可以设置这种对应关系。终于,我们在NSCalendar中发现了firstWeekday这个变量,从字面意思上看貌似就是我们寻找的那个东西。可是,设置过firstWeekday后,我们又发现完全没有作用,真是郁闷啊!其实,大家不必郁闷,因为郁闷也没用,iOS中规定的就是周日为1,周一为2,周二为3,周三为4,周四为5,周五为6,周六为7,无法通过某个设置改变这个事实的,只能在使用的时候注意一下这个规则了。那firstWeekday是干什么用的呢?大家设置一下firstWeekday,再获取一下dateComponents.weekOfYear或dateComponents.weekOfMonth,看看返回的数据是否发生了变化。firstWeekday的作用确实是修改当前历法中周的起始位置,但是不能修改周日对应的数值,只能修改一年或一个月中周的数量,以及周的次序。

-(NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;

我们大致可以理解为:某个时间点所在的“小单元”,在“大单元”中的数量(返回值range的location属性变量的值一般是错误的)。例如:

// 当前时间对应的月份中有几天 
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length; 

// 当前时间对应的月份中有几周(前面说到的firstWeekday会影响到这个结果) 
[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;
-(NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;

我们大致可以理解为:某个时间点所在的“小单元”,在“大单元”中的位置(从1开始)。例如:

// 当前时间对应的周是当前年中的第几周 
[[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekOfYearCalendarUnit inUnit:NSYearCalendarUnit forDate:self]; 
[[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]]; 

// 当前时间对应的周是当前月中的第几周 
[[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekOfMonthCalendarUnit inUnit:NSYearCalendarUnit forDate:self]; 
[[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]];
-(BOOL)rangeOfUnit:(NSCalendarUnit)unit startDate:(NSDate **)datep interval:(NSTimeInterval *)tip forDate:(NSDate *)date;

我们大致可以理解为:“某个时间点”所在的“单元”的起始时间,以及起始时间距离“某个时间点”的时差(单位秒)。例如:

NSDate *startDateOfYear; 
NSDate *startDateOfMonth; 
NSDate *startDateOfWeek; 
NSDate *startDateOfDay; 
NSTimeInterval TIOfYear; 
NSTimeInterval TIOfMonth; 
NSTimeInterval TIOfWeek; 
NSTimeInterval TIOfDay; 

[[NSCalendar currentCalendar] rangeOfUnit:NSYearCalendarUnit startDate:&startDateOfYear interval:&TIOfYear forDate:[NSDate date]]; 
[[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startDateOfMonth interval:&TIOfMonth forDate:[NSDate date]]; 
[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit startDate:&startDateOfWeek interval:&TIOfWeek forDate:[NSDate date]]; 
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startDateOfDay interval:&TIOfDay forDate:[NSDate date]]; 
NSLog(@"firstDateOfYear:%@, FirstDateOfMonth:%@, FirstDateOfWeek:%@, FirstDateOfDay:%@", startDateOfYear, startDateOfMonth, startDateOfWeek, startDateOfDay); NSLog(@"TIOfYear:%f, TIOfMonth:%f, TIOfWeek:%f, TIOfDay:%f", TIOfYear, TIOfMonth, TIOfWeek, TIOfDay);

参考的源文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容