NSCalendar + NSDateComponents

作者: 不会游泳De鱼 | 来源:发表于2016-06-16 20:48 被阅读1665次

    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);
    

    参考的源文章

    相关文章

      网友评论

      • 诗颜语: NSCalendar*calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierChinese];
        NSCalendarUnit unitFlags =NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay;
        NSDateComponents*compToday = [calendar components:unitFlags fromDate:[NSDate date]];//获取不同时间
        我刚刚log了下 compToday.year , compToday.month , compToday.day 三个的值分别为34 6 18 笔者遇到过这个问题么 和 星期那个一样是苹果内定的规则么 那这是什么时间规则 呢?
        诗颜语:@不会游泳De鱼 :+1: 谢谢
        不会游泳De鱼:不好意思,最近没注意。
        NSCalendarIdentifierChinese是指中国农历,按照天干地支分为 "甲子", "乙丑", "丙寅", "丁卯", "戊辰", "己巳", "庚午", "辛未", "壬申", "癸酉", "甲戌", "乙亥", "丙子", "丁丑", "戊寅", "己卯", "庚辰", "辛己", "壬午", "癸未", "甲申", "乙酉", "丙戌", "丁亥", "戊子", "己丑", "庚寅", "辛卯", "壬辰", "癸巳","甲午", "乙未", "丙申", "丁酉", "戊戌", "己亥", "庚子", "辛丑", "壬寅", "癸丑", "甲辰", "乙巳", "丙午", "丁未", "戊申", "己酉", "庚戌", "辛亥", "壬子", "癸丑", "甲寅", "乙卯", "丙辰", "丁巳", "戊午", "己未", "庚申", "辛酉", "壬戌", "癸亥" ,34正好是今年丙申年,百度搜索万年历的时候会有《丙申年 【猴年】庚子月 戊子日 2017年8月22日》。一般使用第一个NSCalendarIdentifierGregorian国际历法就可以
      • FR_Zhang:我想问问,ios8+ 中,NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear这两个有什么区别吗

      本文标题:NSCalendar + NSDateComponents

      本文链接:https://www.haomeiwen.com/subject/ifomdttx.html