【转】iOS NSCalendar日历
原文网址:NSCalendar – CH520 – 博客园 (cnblogs.com)
-
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