美文网首页
NSCalendar使用

NSCalendar使用

作者: 山有木枝壮 | 来源:发表于2019-10-30 19:30 被阅读0次

一、NSCalendar

NSCalendar可以很方便的用来表示日期,获取日期的各种信息,包括年、月、日,时分秒。可以很方便的计算两个日期之前的关系。也可以很方便的根据一个日期获取另一个日期。

NSCalendar中有一个重要的概念NSCalendarUnit,这是一个位枚举,意味着作为参数可以采用位运算的方式传参。

typedef NS_OPTIONS(NSUInteger, NSCalendarUnit) {
        // 公元前、公元后
        NSCalendarUnitEra                = kCFCalendarUnitEra,
        // 获取年、月、日
        NSCalendarUnitYear               = kCFCalendarUnitYear,
        NSCalendarUnitMonth              = kCFCalendarUnitMonth,
        NSCalendarUnitDay                = kCFCalendarUnitDay,
        // 获取时、分、秒
        NSCalendarUnitHour               = kCFCalendarUnitHour,
        NSCalendarUnitMinute             = kCFCalendarUnitMinute,
        NSCalendarUnitSecond             = kCFCalendarUnitSecond,
        // 获取周几  周日为1 、周1为2
        NSCalendarUnitWeekday            = kCFCalendarUnitWeekday,
        // 获取本周是本月的第几周,7天为1个单位
        NSCalendarUnitWeekdayOrdinal     = kCFCalendarUnitWeekdayOrdinal,
        // 获取刻钟,15分钟为1刻钟
        NSCalendarUnitQuarter            API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = kCFCalendarUnitQuarter,
        // 本月第几周
        NSCalendarUnitWeekOfMonth        API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = kCFCalendarUnitWeekOfMonth,
        // 本年第几周
        NSCalendarUnitWeekOfYear         API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = kCFCalendarUnitWeekOfYear,
        NSCalendarUnitYearForWeekOfYear  API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = kCFCalendarUnitYearForWeekOfYear,
        // 纳秒
        NSCalendarUnitNanosecond         API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = (1 << 15),
        NSCalendarUnitCalendar           API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)) = (1 << 20),
        NSCalendarUnitTimeZone           API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)) = (1 << 21),
}

如下所示,使用上面的位组件,可以方便的获取一个时间的年月日等信息

NSDateComponents *comps = [NSCalendar.currentCalendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]];

另外一个比较重要的类是NSDateComponents,上面是通过位参数获取每个单位(年月日)的信息,返回的结构可以看到是一个NSDateComponents,如果我要表示一个日期的信息,构建日期或者进行日期的计算,就少不了NSDateComponents,它可以将日期按照单位的形式封装起来,然后通过NSCalendar的方法进行计算

  • NSDateComponents中表示日期的单位与上面的位枚举NSCalendarUnit基本类似,用的时候只需要新建并且赋值即可
        // 构建一个日期
        NSDateComponents *mycoms = [NSDateComponents new];
        mycoms.year = 2018;
        mycoms.month = 1;
        mycoms.day = 3;
        NSLog(@"%@", [NSCalendar.currentCalendar dateFromComponents:mycoms]);

        // 如下:在当前日期加上3天
        NSDateComponents *coms = [NSDateComponents new];
        coms.day = 3;
        NSDate *newDate = [NSCalendar.currentCalendar dateByAddingComponents:coms toDate:[NSDate date] options:0];
        NSLog(@"%@", newDate);

了解NSCalendarUnit和NSDateComponents之后,再回过头看NSCalendar的初始化方法

NSCalendar提供了4中初始化方法

// 使用用户手机设置的日期信息,有缓存,用户手机日历改变后不会变
@property (class, readonly, copy) NSCalendar *currentCalendar;  
// 使用用户手机设置的日期信息,并且用户改变之后会跟着改变
@property (class, readonly, strong) NSCalendar *autoupdatingCurrentCalendar API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // tracks changes to user's preferred calendar identifier
// 使用指定的标识获取日期,比如农历、佛历,常用的是格里高利历(NSCalendarIdentifierGregorian)
+ (nullable NSCalendar *)calendarWithIdentifier:(NSCalendarIdentifier)calendarIdentifierConstant API_AVAILABLE(macos(10.9), ios(8.0), watchos(2.0), tvos(9.0));
- (nullable id)initWithCalendarIdentifier:(NSCalendarIdentifier)ident NS_DESIGNATED_INITIALIZER;
  • NSCalendar中有一个属性firstWeekday,代表周几作为一周的开始。默认周日是一周的开始,如果设置firstWeekDay = 2,代表着周一作为一周的开始,但是设置了该值之后,并不会改变NSCalendarUnitWeekday的值,如果是周日,该值返回的还是1,并不是7。该值设置只会可以用于计算两个日期是否在同一周,比如按照之前的设置,周日、周一周六是同一周,如果设置周一是起始日,那么周一、周二周日才是同一周。同理,在计算今天一年的第几周时同样受改属性影响

  • NSCalendar可以方便的获取国际化的月份信息,比如英语一月标识为February。设置NSCalendar的NSLocale之后,使用属性monthSymbols可以获取全部的月份表示,这样做国际化处理的时候只要获取月份,然后从数组中取出对应的值即可

用来表示最小或者最大的范围,比如月份最小返回1~28,最大为1~31
- (NSRange)minimumRangeOfUnit:(NSCalendarUnit)unit;
- (NSRange)maximumRangeOfUnit:(NSCalendarUnit)unit;
  • 用来表示大范围内的小范围的取值范围获取具体数值
// 当前时间对应的月份中有几天
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length; 
// 当前时间对应的月份中有几周(前面说到的firstWeekday会影响到这个结果)
[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;
// 当前时间对应的周是当前年中的第几周
[[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]];

  • 判断给定日期是否为今天、昨天、明天或者周末
isDateInToday
isDateInYesterday
isDateInTomorrow
isDateInWeekend
  • 计算两个日期之间的间隔,使用NSDateComponents表示
- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSCalendarOptions)opts;
  • 根据NSCalendarUnit比较两个时间
- (NSComparisonResult)compareDate:(NSDate *)date1 toDate:(NSDate *)date2 toUnitGranularity:(NSCalendarUnit)unit

二、NSDate

要使用NSCalendar,离不开NSDate。

NSDate用来表示一个具体的时间,默认时区为0时区,在中国使用的是GMT+8,代表比0时区偏移8个小时。

在iOS中获取的时间都是基于0时区的,因此在中国获取的时间会少8个小时,需要使用下面的方式追加时间差值,或者使用NSDateFormatter的时候指定时区

// 得到当前时间(世界标准时间 UTC/GMT) 
NSDate *date = [NSDate date]; 
// 设置系统时区为本地时区 
NSTimeZone *zone = [NSTimeZone systemTimeZone]; 
// 计算本地时区与 GMT 时区的时间差 
NSInteger interval = [zone secondsFromGMT]; 
// 在 GMT 时间基础上追加时间差值,得到本地时间 
date = [date dateByAddingTimeInterval:interval];

三、NSTimeZone

用来表示时区信息

// 系统支持时区简写
abbreviationDictionary

四、NSLocale

用来表示本地化的相关信息.
每一个NSLocale实例对应着一个地区标识符,例如en_US,fr_FR,ja_JP和en_GB,这些标识符包含一个语言码(例如en代表英语)和一个地区码(例如US代表美国)

@property (class, readonly, copy) NSArray<NSString *> *ISOLanguageCodes;//所有ISO定义的语言编码`
@property (class, readonly, copy) NSArray<NSString *> *ISOCountryCodes;//所有的ISO定义的国家地区编码`
@property (class, readonly, copy) NSArray<NSString *> *ISOCurrencyCodes;//所有的ISO定义的货币编码`

参考文章:
1、NSLocale使用

相关文章

网友评论

      本文标题:NSCalendar使用

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