博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS - OC NSCalendar 日历
阅读量:5892 次
发布时间:2019-06-19

本文共 10095 字,大约阅读时间需要 33 分钟。

前言

@interface NSCalendar : NSObject 
  • NSCalendar 对世界上现存的常用的历法进行了封装,既提供了不同历法的时间信息,又支持日历的计算。

    • NSCalendar -- 日历类,它提供了大部分的日期计算接口,并且允许您在NSDate和NSDateComponents之间转换
    • NSTimeZone -- 时区信息
    • NSLocale -- 本地化信息
    • NSDate -- 表示一个绝对的时间点
    • NSDateComponents -- 一个封装了具体年月日、时秒分、周、季度等的类
    • NSDateFormatter -- 用来在日期和字符串之间转换
  • 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 的作用确实是修改当前历法中周的起始位置,但是不能修改周日对应的数值,只能修改一年或一个月中周的数量,以及周的次序。

1、日历的创建

// 根据提供的日历标示符初始化。    /*        identifier 的范围可以是:                        NSCalendarIdentifierGregorian         公历            NSCalendarIdentifierBuddhist          佛教日历            NSCalendarIdentifierChinese           中国农历            NSCalendarIdentifierHebrew            希伯来日历            NSCalendarIdentifierIslamic           伊斯兰日历            NSCalendarIdentifierIslamicCivil      伊斯兰教日历            NSCalendarIdentifierJapanese          日本日历            NSCalendarIdentifierRepublicOfChina   中华民国日历(台湾)            NSCalendarIdentifierPersian           波斯历            NSCalendarIdentifierIndian            印度日历            NSCalendarIdentifierISO8601           ISO8601    */    NSCalendar *cal1 = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];    // 返回当前客户端的逻辑日历    /*        取得的值会一直保持在 cache 中,第一次用此方法实例化对象后,即使修改了系统日历设定,这个对象也不会改变    */    NSCalendar *cal2 = [NSCalendar currentCalendar];        // 返回当前客户端的逻辑日历    /*        当每次修改系统日历设定,其实例化的对象也会随之改变    */    NSCalendar *cal3 = [NSCalendar autoupdatingCurrentCalendar];

2、日历的设置

NSCalendar *calendar = [NSCalendar currentCalendar];        // 设置区域    [calendar setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];        // 设置时区    /*        设置时区,设置为 GMT+8,即北京时间(+8)    */    [calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"CCT"]];    [calendar setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:+28800]];        // 设定每周的第一天从星期几开始    /*        1 代表星期日开始,2 代表星期一开始,以此类推。默认值是 1    */    [calendar setFirstWeekday:2];        // 设置每年及每月第一周必须包含的最少天数    /*        设定第一周最少包括 3 天,则 value 传入 3    */    [calendar setMinimumDaysInFirstWeek:3];

3、日历设置信息的获取

NSCalendar *calendar = [NSCalendar currentCalendar];        // 获取日历标示符    /*        有效的日历标示符包括:                    gregorian            buddhist            chinese            hebrew            islamic            islamic-civil            japanese            roc            persian            indian            iso8601    */    NSString *calendarIdentifier =  calendar.calendarIdentifier;        // 获取地区信息    /*        语言地区    */    NSString *localeIdentifier = calendar.locale.localeIdentifier;    NSString *localeIdentifier2 = [calendar.locale objectForKey:NSLocaleIdentifier];            // 获取时区信息    NSTimeZone *timeZone = calendar.timeZone;            // 获取每周的第一天从星期几开始    /*        缺省为星期天    */    NSUInteger firstWeekday = calendar.firstWeekday;            // 获取第一周必须包含的最少天数    /*        缺省为 1    */    NSUInteger minimumDaysInFirstWeek = calendar.minimumDaysInFirstWeek;

4、日历信息的获取

  • 1)获取一个小的单位在一个大的单位里面的序数

    NSUInteger count = [calendar ordinalityOfUnit:NSCalendarUnitWeekday                                            inUnit:NSCalendarUnitWeekOfMonth                                           forDate:[NSDate date]];
    - (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;    NSCalendarUnit包含的值有:        NSCalendarUnitEra                 -- 纪元单位。对于 NSGregorianCalendar (公历)来说,只有公元前(BC)和公元(AD);                                             而对于其它历法可能有很多,例如日本和历是以每一代君王统治来做计算。        NSCalendarUnitYear                -- 年单位。值很大,相当于经历了多少年,未来多少年。        NSCalendarUnitMonth               -- 月单位。范围为1-12        NSCalendarUnitDay                 -- 天单位。范围为1-31        NSCalendarUnitHour                -- 小时单位。范围为0-24        NSCalendarUnitMinute              -- 分钟单位。范围为0-60        NSCalendarUnitSecond              -- 秒单位。范围为0-60        NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear -- 周单位。范围为1-53        NSCalendarUnitWeekday             -- 星期单位,每周的7天。范围为1-7        NSCalendarUnitWeekdayOrdinal      -- 没完全搞清楚        NSCalendarUnitQuarter             -- 几刻钟,也就是15分钟。范围为1-4        NSCalendarUnitWeekOfMonth         -- 月包含的周数。最多为6个周        NSCalendarUnitWeekOfYear          -- 年包含的周数。最多为53个周        NSCalendarUnitYearForWeekOfYear   -- 没完全搞清楚        NSCalendarUnitTimeZone            -- 没完全搞清楚    <1>、当小单位为 NSCalendarUnitWeekday,大单位为 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear 时         (即某个日期在这一周是第几天),根据 firstWeekday 属性不同,返回的结果也不同。具体说明如下:        当 firstWeekday 被指定为星期天(即 = 1)时,它返回的值与星期几对应的数值保持一致。比如:            fromDate 传入的参数是星期日,则函数返回 1            fromDate 传入的参数是星期一,则函数返回 2        当 firstWeekday 被指定为其它值时(即 <> 1)时,假设firstWeekday 被指定为星期一(即 = 2),那么:            fromDate 传入的参数是星期一,则函数返回 1            fromDate 传入的参数是星期二,则函数返回 2            fromDate 传入的参数是星期日,则函数返回 7    <2>、当小单位为 参数为 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear,大单位为 NSCalendarUnitYear 时         (即某个日期在这一年中是第几周),minimumDaysInFirstWeek 属性影响它的返回值。具体说明如下:            2005年1月            日   一    二   三   四    五   六            --------------------------------                                          1            2    3    4    5    6    7    8            9    10   11   12   13   14   15            16   17   18   19   20   21   22            23   24   25   26   27   28   29            30   31            2005年1月第一周包括1号。            a. 如果将 minimumDaysInFirstWeek 设定 = 1            则 fromDate 传入1月1号,方法均返回1  ==> 满足 minimumDaysInFirstWeek 指定的天数(最少1天),所以方法将其归为                                                  2005年的第1周            则 fromDate 传入1月2-8号,方法均返回2            则 fromDate 传入1月9-15号,方法均返回3            ......            b. 如果将 minimumDaysInFirstWeek 设定为 > 1,比如2            则 fromDate 传入1月1号,方法均返回53  ==> 不足2天,所以方法将其归为2004年的第53周            则 fromDate 传入1月2-8号,方法均返回1            则 fromDate 传入1月9-15号,方法均返回2            ......            2008年1月            日   一    二   三   四    五   六            ---------------------------------                      1    2    3    4    5            6    7    8    9    10   11   12            13   14   15   16   17   18   19            20   21   22   23   24   25   26            27   28   29   30   31            2005年1月第一周包括1-5号共5天。            a. 如果将 minimumDaysInFirstWeek 设定为 <= 5时            则 fromDate 传入1月1-5号,方法均返回1  ==> 满足 minimumDaysInFirstWeek 指定的天数,所以方法将其归为2008年的第1周            则 fromDate 传入1月6-12号,方法均返回2            则 fromDate 传入1月13-19号,方法均返回3            ......            b. 如果将 minimumDaysInFirstWeek 设定为 > 5,比如6            则 fromDate 传入1月1-5号,方法均返回53  ==> 当周不足6天,所以方法将其归为2007年的第53周            则 fromDate 传入1月2-8号,方法均返回1            则 fromDate 传入1月9-15号,方法均返回2            ......    <3>、当小单位为 参数为 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear,大单位为 NSCalendarUnitMonth 时         (即某个日期在这一个月中是第几周),minimumDaysInFirstWeek 属性影响它的返回值。具体说明如下:            2008年4月            日   一    二   三   四    五   六            ---------------------------------                      1    2    3    4    5            6    7    8    9    10   11   12            13   14   15   16   17   18   19            20   21   22   23   24   25   26            27   28   29   30            2008年4月第一周包括1、2、3、4、5号。            a. 如果将 minimumDaysInFirstWeek 设定为小于或等于5的数            则 fromDate 传入4月1-5号,方法均返回1            则 fromDate 传入4月6-12号,方法均返回2            则 fromDate 传入4月13-19号,方法均返回3            ....            b. 如果将 minimumDaysInFirstWeek 设定为大于5的数            则 fromDate 传入1-5号,方法均返回0            则 fromDate 传入6-12号,方法均返回1            则 fromDate 传入13-19号,方法均返回2            ....
  • 2)获取一个小的单位在一个大的单位里面的取值范围

    NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:[NSDate date]];    NSLog(@"%zi -- %zi", range.location, range.length);
    - (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;    调用这个方法要明确一点,取得的是"范围"而不是"包含",下面是一些例子:    <1>、小单位是 NSCalendarUnitDay,大单位是 NSCalendarUnitYear,并不是要取这一年包含多少天,而是要取"天"(Day)这个单位         在这一年(Year)的取值范围。其实不管你提供的日期是多少,返回的值都是"1--31"。    <2>、小单位是 NSCalendarUnitDay,大单位是 NSCalendarUnitMonth。要取得参数时间点所对应的月份下,"天"(Day)的取值范围。         根据参数时间的月份不同,值也不同。例如2月是1--28、3月是 1--31、4月是1--30。    <3>、小单位是 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear,大单位是 NSCalendarUnitMonth。要取得参数         时间点所对应的月份下,"周"(Week)的取值范围。需要注意的是结果会受到 minimumDaysInFirstWeek 属性的影响。在默认          minimumDaysInFirstWeek 情况下,取得的范围值一般是"1--5",从日历上可以看出来这个月包含5排,即5个周。    <4>、小单位是 NSCalendarUnitDay,大单位是 NSCalendarUnitWeekOfMonth / NSCalendarUnitWeekOfYear。要取得周所包含         的"天"(Day)的取值范围。下面是一个示例日历图:            2013年4月            日   一    二   三   四    五   六            ---------------------------------                 1    2    3    4    5    6                7    8    9    10   11   12  13               14   15   16   17   18   19  20               21   22   23   24   25   26  27               28   29   30            在上图的日期条件下,假如提供的参数是4月1日--4月6日,那么对应的 week 就是1(第一个周),可以看到第一个周包含有6天,        从1号开始,那么最终得到的范围值为1--6。        假如提供的参数是4月18日,那么对应的 week 是3(第三个周),第三个周包含有7天,从14号开始,那么最终得到的范围值是14--7。        假如提供的参数是4月30日,那么对应的 week 是5(第五个周),第五个周只包含3天,从28号开始,那么最终得到的范围值是28--3。
  • 3)获取所在日历单位的开始时间及所在日历单位的总秒数

    NSDate *startDate = nil;    NSTimeInterval intervalCount = 0;    BOOL bl = [calendar rangeOfUnit:NSCalendarUnitMonth                           startDate:&startDate                            interval:&intervalCount                             forDate:[NSDate date]];    if (bl) {        // 得到本地时间,避免时区问题        startDate = [startDate dateByAddingTimeInterval:[[NSTimeZone systemTimeZone] secondsFromGMTForDate:startDate]];        NSLog(@"%@",startDate);        NSLog(@"%f",intervalCount);    }    else {        NSLog(@"无法计算");    }

转载于:https://www.cnblogs.com/QianChia/p/5782755.html

你可能感兴趣的文章
ARC 下两种释放对象的方法
查看>>
scala中的continue和break
查看>>
edx 获取当前request
查看>>
亚马逊Kindle将会入华?
查看>>
谁的青春不迷茫
查看>>
flash actionscript 3.0 动画教程:函数之形式参数和实际参数
查看>>
算法导论-分治、最大子序列问题
查看>>
安卓中如何实现滑动导航
查看>>
Java-金额小数转换成中文大写金额
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
squid.3.2故障整理
查看>>
Ansible Tower安装配置全过程(上)
查看>>
地址与引用
查看>>
十大开源ERP点评 献给深水区的中小企业和CIO们
查看>>
Cacti开源监控系统的安装、配置、优化及运维技术文档
查看>>
MNIST机器学习入门-基于TensorFlow
查看>>
Oracle --存储函数和存储过程
查看>>
Windows Server 2008 R2 SP1 关闭IE ESC (Internet Explorer 增强的安全配置)
查看>>
套接字编程——基于TCP协议
查看>>