博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ios时间那点事 NSCalendar NSDateComponents
阅读量:6824 次
发布时间:2019-06-26

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

#原址:https://my.oschina.net/yongbin45/blog/156181 ###NSCalendar + NSDateComponents

  • 历法能使人类确定每一日再无限的时间中的确切位置并记录历史。
  • 日历,历法,一般历法都是遵循固定的规则的,具有周期性。日历都是已知的或可预测的。
  • 任何一种具体的历法,首先必须明确规定起始点,即开始计算的年代,这叫“纪元”;以及规定一年的开端,这叫“岁首”。此外,还要规定每年所含的日数,如何划分月份,每月有多少天等等。
  • NSCalendar对世界上现存的常用的历法进行了封装,既提供了不同历法的时间信息,又支持日历的计算。
  • NSDateFomatter表示的时间默认以公历(即阳历)为参考,可以通过设置calendar属性变量获得特定历法下的时间表示。
  • NSDate是独立与任何历法的,它只是时间相对于某个时间点的时间差;NSDate是进行日历计算的基础。
  • NSDateComponents将时间表示成适合人类阅读和使用的方式,通过NSDateComponents可以快速而简单地获取某个时间点对应的“年”,“月”,“日”,“时”,“分”,“秒”,“周”等信息。当然一旦涉及了年月日时分秒就要和某个历法绑定,因此NSDateComponents必须和NSCalendar一起使用,默认为公历。
  • NSDateComponents除了像上面说的表示一个时间点外,还可以表示时间段,例如:两周,三个月,20年,7天,10分钟,50秒等等。时间段用于日历的计算,例如:获取当前历法下,三个月前的某个时间点。
  • 可以说,要获取某个时间点在某个历法下的表示,需要NSDateComponents;要计算当前时间点在某个历法下对应的一个时间段前或后的时间点,需要NSDateComponents。
  • NSDateComponents返回的day, week, weekday, month, year这一类数据都是从1开始的。因为日历是给人看的,不是给计算机看的,从0开始就是个错误。 ##NSDateComponents实例化的方式 ####第一种:
//    先定义一个遵循某个历法的日历对象NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];//    通过已定义的日历对象,获取某个时间点的NSDateComponents表示,并设置需要表示哪些信息(NSYearCalendarUnit, NSMonthCalendarUnit, NSDayCalendarUnit等)NSDateComponents *dateComponents = [greCalendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit | NSWeekOfMonthCalendarUnit | NSWeekOfYearCalendarUnit fromDate:[NSDate date]];NSLog(@"year(年份): %i", dateComponents.year);NSLog(@"quarter(季度):%i", dateComponents.quarter);NSLog(@"month(月份):%i", dateComponents.month);NSLog(@"day(日期):%i", dateComponents.day);NSLog(@"hour(小时):%i", dateComponents.hour);NSLog(@"minute(分钟):%i", dateComponents.minute);NSLog(@"second(秒):%i", dateComponents.second);//    Sunday:1, Monday:2, Tuesday:3, Wednesday:4, Friday:5, Saturday:6NSLog(@"weekday(星期):%i", dateComponents.weekday);//    苹果官方不推荐使用weekNSLog(@"week(该年第几周):%i", dateComponents.week);NSLog(@"weekOfYear(该年第几周):%i", dateComponents.weekOfYear);NSLog(@"weekOfMonth(该月第几周):%i", dateComponents.weekOfMonth);复制代码

####第二种:

//    先定义一个遵循某个历法的日历对象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];[dateComponentsForDate setDay:6];//    在当前历法下,获取6天后的时间点NSDate *dateFromDateComponentsAsTimeQantum = [greCalendar dateByAddingComponents:dateComponentsAsTimeQantum toDate:[NSDate date] options:0];复制代码

####第三种:

//    先定义一个遵循某个历法的日历对象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:%i", 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的作用确实是修改当前历法中周的起始位置,但是不能修改周日对应的数值,只能修改一年或一个月中周的数量,以及周的次序。

##1-(NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date; 答疑解惑:

  • Unit:单元
  • NSRange:
typedef struct _NSRange {     NSUInteger location;     NSUInteger length;} NSRange;复制代码

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

//    当前时间对应的月份中有几天    [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;    //    当前时间对应的月份中有几周(前面说到的firstWeekday会影响到这个结果)    [[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;复制代码

##2-(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]];复制代码

在这里:NSWeekOfYearCalendarUnit, NSWeekOfMonthCalendarUnit与NSWeekCalendarUnit的使用结果相同,为了避免浑淆,建议在此处使用NSWeekCalendar,而定义NSDateComponents时使用NSWeekOfYearCalendarUnit和NSWeekOfMonthCalendarUnit。 ##3-(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);复制代码

转载地址:http://slrzl.baihongyu.com/

你可能感兴趣的文章
跨交换机实现VLAN
查看>>
XML - JAXP技术 - DOM解析
查看>>
数据操作与查询语句
查看>>
selenium webdriver (11) -- 截图
查看>>
sublime插件安装
查看>>
网络配置多会话实验
查看>>
如何挑选适合自己的HTML5视频课程
查看>>
windows提权
查看>>
苹果Siri再新增服务内容 航班查询、餐点外送和血糖监控
查看>>
学习笔记
查看>>
远程协助,TeamViewer之外的另一种选择
查看>>
Centos 6.5 部署 LNMP
查看>>
网安天目
查看>>
rsync远程同步及rsync+inotify实时同步
查看>>
Redis分布式锁的正确实现方式(Java版)
查看>>
Linux20180427
查看>>
linux系统配置及服务管理第一章系统部署
查看>>
SQL语句优化:show参数
查看>>
webstorm那些常用快捷键
查看>>
MySQL5.7 group by新特性报错1055的解决办法
查看>>