iOS学习笔记37-时间和日期计算

一、时间和日期计算

我们在应用开发中,时常需要和时间打交道,比如获取当前时间,获取两个时间点相隔的时间等等,在iOS开发中与时间相关的类有如下几个:

1. NSDate:表示一个绝对的时间点

2. NSTimeZone:时区信息

3. NSLocale:本地化信息

4. NSDateComponents:一个封装了具体年月日、时秒分、周、季度等的类

5. NSCalendar:日历类,它提供了大部分的日期计算接口

6. NSDateFormatter:用来在日期和字符串之间转换

二、NSDate时间点

NSDate存储的是世界标准时(UTC),输出时需要根据时区转换为本地时间

NSDate常用初始化方法:
/* 获取当前时间,alloc/init得到的时间也是当前时间 */
+ (instancetype)date;
/* 以当前时间为基准,获取偏移秒数的时间 */
+ (instancetype)dateWithTimeIntervalSinceNow:(NSTimeInterval)seconds;
/* 以1970年1月1日为基准,获取偏移秒数的时间 */
+ (instancetype)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds;
/* 以2001年1月1日为基准,获取偏移秒数的时间 */
+ (instancetype)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)seconds;
/* 以指定时间点为基准,获取偏移秒数的时间 */
+ (instancetype)dateWithTimeInterval:(NSTimeInterval)seconds
                           sinceDate:(NSDate *)date;
/* 获取一个极早的时间点,0001-12-30 00:00:00 +0000 */
+ (instancetype)distantPast;
/* 获取一个极晚的时间点,4001-01-01 00:00:00 +0000 */
+ (instancetype)distantFuture;
  • 除了最后的2个获取极早极晚时间的方法,其他方法都有对应的init前缀方法。
  • 极早和极晚时间常用于定时器的开始和暂停
  • 偏移秒数为正,表示比基准时间晚的时间,偏移秒数为负,表示比基准时间早的时间
NSDate常用的对象方法:
/* 以当前NSDate对象为基准,获取偏移指定秒数后得到的新NSDate对象 */
- (instancetype)dateByAddingTimeInterval:(NSTimeInterval)seconds;
#pragma mark - 比较2个时间
/* 比较2个NSDate对象,返回较早的那个NSDate时间点对象 */
- (NSDate *)earlierDate:(NSDate *)anotherDate;
/* 比较2个NSDate对象,返回较晚的那个NSDate时间点对象 */
- (NSDate *)laterDate:(NSDate *)anotherDate;
/* 比较2个NSDate对象,返回枚举类型(相等、早于、晚于) */
- (NSComparisonResult)compare:(NSDate *)anotherDate;
#pragma mark - 获取相隔秒数,从参数时间开始,经过多少秒到达对象执行时间
/* 返回当前对象时间与1970年1月1日00:00:00的相隔秒数 */
- (NSTimeInterval)timeIntervalSince1970;
/* 返回当前对象时间与2001年1月1日00:00:00的相隔秒数 */
- (NSTimeInterval)timeIntervalSinceReferenceDate;
/* 返回当前对象时间与当前客户端时间的相隔秒数 */
- (NSTimeInterval)timeIntervalSinceNow;
/* 返回当前对象时间与指定时间的相隔秒数 */
- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate;
下面是使用实例:
/* 获取当前客户端时间 */
NSDate *date1 = [NSDate date];
/* 获取比date1晚30秒的时间 */
NSDate *date2 = [NSDate dateWithTimeInterval:30 sinceDate:date1];
/* 比较2个时间,获取较早的时间和较晚的时间 */
NSDate *earlierDate = [date1 earlierDate:date2];
NSDate *laterDate   = [date1 laterDate:date2];
NSLog(@"earlierDate:%@,laterDate:%@",earlierDate,laterDate);
/* 比较2个时间 */
NSComparisonResult result = [date1 compare:date2];
switch(result){
    case NSOrderedSame:
        NSLog(@"对象时间等于参数时间");
        break;
    case NSOrderedAscending:
        NSLog(@"对象时间早于参数时间");
        break;
    case NSOrderedDescending:
        NSLog(@"对象时间晚于参数时间");
        break;
}
/* 获取相隔时间秒数,将返回结果-30,从date2的时间开始,倒退30秒到达date1的时间 */
NSTimeInterval seconds = [date1 timeIntervalSinceDate:date2];
NSLog(@"date1与date2相隔%@秒",seconds);

三、NSTimeZone时区

NSTimeZone常用初始化方法:
/* 根据时区名称初始化,例如:America/Chicago(美国芝加哥) */
+ (instancetype)timeZoneWithName:(NSString *)aTimeZoneName;
/* 根据时区缩写初始化,例如:EST(美国东部标准时间)、HKT(香港标准时间) */
+ (instancetype)timeZoneWithAbbreviation:(NSString *)abbreviation;
/* 返回系统时区 */
+ (NSTimeZone *)systemTimeZone;
/* 返回本地时区 */
+ (NSTimeZone *)localTimeZone;
  • 时区名称可以通过以下方法获取:
/* 以数组形式返回所有已知的时区名称 */
+(NSArray *)knownTimeZoneNames;
  • 本地时区和系统时区的区别在于本地时区可以被修改,而系统时区不能修改
NSTimeZone常用对象方法:
/* 获取时区名称 */
- (NSString *)name;
/* 获取时区缩写 */
- (NSString *)abbreviation;
/* 获取对象时区与零时区的间隔秒数 */
- (NSInteger)secondsFromGMT;

四、NSLocale本地化信息

NSLocale类返回本地化信息,主要体现在语言区域格式这两个设置项。

NSLocale常用初始化方法:
/* 返回系统初始本地化信息 */
+(instancetype)systemLocale;
/* 返回当前客户端的本地化信息,即使修改了本地化设定,这个对象也不会改变 */
+(instancetype)currentLocale;
/* 返回当前客户端的本地化信息,当每次修改本地化设定,其实例化的对象会随之改变 */
+(instancetype)autoupdatingCurrentLocale;
/* 用标示符初始化本地化信息,例如:en_US */
-(instancetype)initWithLocaleIdentifier:(NSString *)string;
NSLocale常用对象方法:
/* 根据不同的key返回各种本地化信息 */
- (id)objectForKey:(id)key;
/* 显示特定地区代号下相应键的显示名称 */
- (NSString *)displayNameForKey:(id)key
                          value:(id)value;
以下是使用实例:
//获取系统本地化信息
NSLocale *sysLocale = [NSLocale systemLocale];
//获取客户端本地化信息,不可响应修改
NSLocale *curLocale = [NSLocale currentLocale];
//获取客户端本地化信息,可动态响应修改
NSLocale *autoCurLocale = [NSLocale autoupdatingCurrentLocale];
//通过标识创建自定义本地化信息
NSLocale *userLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
//获取货币符号
NSString *strSymbol = [userLocale objectForKey:NSLocaleCurrencySymbol];
NSLog(@"货币符号:%@",strSymbol);//打印:¥
//获取本地日历
NSCalendar *calendar = [userLocale objectForKey:NSLocaleCalendar];
NSLog(@"本地日历:%@",calendar);
//得到"en_US"的NSLocaleIdentifier键的显示名称
NSString *str = [userLocale displayNameForKey:NSLocaleIdentifier value:@"en_US"];
NSLog(@"标识显示名称:%@",str);//打印:英文(美国)

五、NSDateComponents时间封装

NSDateComponents封装了具体年月日、时秒分、周、季度等:

/* 创建一个日期对象 */
NSDateComponents*compt = [[NSDateComponents alloc] init];
[compt setEra:1];//纪元
[compt setYear:2013];//年
[compt setMonth:3];//月
[compt setDay:15];//日
[compt setHour:11];//小时
[compt setMinute:20];//分钟
[compt setSecond:55];//秒钟
[compt setQuarter:2];//几刻钟
[compt setTimeZone:[NSTimeZone systemTimeZone]];//时区
[compt setWeek:3];//一年的第几周
[compt setWeekday:4];//周几
[compt setWeekOfMonth:3];//一个月的第几周
[compt setWeekOfYear:3];//一年的第几周
[compt setCalendar:[NSCalendar currentCalendar]];//日历

NSDateComponents通常不单独使用,它经常与时间点NSDate、日历类NSCalendar一起使用

六、NSCalendar日历类

NSCalendar类,表示日历,封装了大量的计算日期方法

NSCalendar常用创建方法:
/* 返回客户端的逻辑日历,即使修改了系统日历设定,这个对象也不会改变 */
+(instancetype)currentCalendar;
/* 返回客户端的逻辑日历,修改了系统日历设定,这个对象会随之改变 */
+(instancetype)autoupdatingCurrentCalendar;
/* 根据提供的日历标示符初始化 */
-(instancetype)initWithCalendarIdentifier:(NSString *)string;
系统中定义的日历标识符有:
  • NSGregorianCalendar:公历
  • NSBuddhistCalendar:佛教日历
  • NSChineseCalendar:中国农历
  • NSHebrewCalendar:希伯来日历
  • NSIslamicCalendar:伊斯兰历
  • NSIslamicCivilCalendar:伊斯兰教日历
  • NSJapaneseCalendar:日本日历
  • NSRepublicOfChinaCalendar:中华民国日历(台湾)
  • NSPersianCalendar:波斯历
  • NSIndianCalendar:印度日历
  • NSISO8601Calendar:ISO8601日历
NSCalendar常用的与NSDateComponents相关对象方法:
/*
  取得一个NSDate对象的1个或多个部分转为NSDateComponents,
  只有明确指定了unitFlags,NSDateComponents相应的那一部分才有值
 */
- (NSDateComponents *)components:(NSUInteger)unitFlags
                        fromDate:(NSDate *)date;
/* 取得两个NSDate对象的时间间隔,用NSDateComponents来封装 */
- (NSDateComponents *)components:(NSUInteger)unitFlags
                        fromDate:(NSDate *)startingDate
                          toDate:(NSDate*)resultDate
                         options:(NSUInteger)opts;/* 一般默认传0即可 */
/* 根据NSDateComponents对象得到一个NSDate对象 */
- (NSDate *)dateFromComponents:(NSDateComponents *)comps;
/* 在参数date基础上,增加一个NSDateComponents类型的时间增量 */
- (NSDate *)dateByAddingComponents:(NSDateComponents *)comps
                            toDate:(NSDate *)date
                           options:(NSUInteger)opts;/* 一般默认传0即可 */

unitFlags参数通过下面的日历单位NSCalendarUnit用或运算“|”组合使用

日历单位NSCalendarUnit,可以用或运算“|”组合使用:
  • NSEraCalendarUnit

    纪元单位。对于NSGregorianCalendar(公历)来说,只有公元前(BC)和公元(AD);而对于其它历法可能有很多,例如日本和历是以每一代君王统治来做计算。

  • NSYearCalendarUnit:年单位。值很大,相当于经历了多少年,未来多少年。
  • NSMonthCalendarUnit:月单位。范围为1-12
  • NSDayCalendarUnit:天单位。范围为1-31
  • NSHourCalendarUnit:小时单位。范围为0-24
  • NSMinuteCalendarUnit:分钟单位。范围为0-60
  • NSSecondCalendarUnit:秒单位。范围为0-60
  • NSWeekCalendarUnit:周单位。范围为1-53
  • NSWeekdayCalendarUnit:星期单位,每周的7天。范围为1-7
  • NSWeekdayOrdinalCalendarUnit:没完全搞清楚
  • NSQuarterCalendarUnit:几刻钟,也就是15分钟。范围为1-4
  • NSWeekOfMonthCalendarUnit:月包含的周数。最多为6个周
  • NSWeekOfYearCalendarUnit:年包含的周数。最多为53个周
  • NSYearForWeekOfYearCalendarUnit:没完全搞清楚
  • NSTimeZoneCalendarUnit:没完全搞清楚
以下是使用实例:
//获取客户端逻辑日历
NSCalendar *calendar = [NSCalendar currentCalendar];
//获取当前时间
NSDate *date = [NSDate date];
//从date中读取年月日,存储在NSDateComponents对象中
NSDateComponents *compt1 = [calendar components:(NSYearCalendarUnit |
                                                 NSMonthCalendarUnit |
                                                 NSDayCalendarUnit)
                                       fromDate:date];

NSLog(@"年:%d",[compt1 year]);//2016
NSLog(@"月:%d",[compt1 month]);//4
NSLog(@"日:%d",[compt1 day]);//19
/*********************************************************************/
//创建一个时间相差5小时1分15秒的时间点
NSDate *date2 = [NSDate dateWithTimeInterval:5*60*60+1*60+15
                                   sinceDate:date];
//时间间隔NSDate转NSDateComponents,分钟加秒钟
NSDateComponents *compt2 = [calendar components:(NSMinuteCalendarUnit |
                                                 NSSecondCalendarUnit)
                                       fromDate:date
                                         toDate:date2
                                        options:0];

NSLog(@"时间间隔【分种加秒钟】:%d分%d秒",[compt2 minute],[compt2 second]);//301分15秒
//时间间隔NSDate转NSDateComponents,只有秒钟
NSDateComponents *compt3 = [calendar components:NSSecondCalendarUnit
                                       fromDate:date
                                         toDate:date2
                                        options:0];
NSLog(@"时间间隔【秒数】:%d秒",[compt3 second]);//18075秒
/*********************************************************************/
//创建自定义NSDateComponents对象
NSDateComponents *compt4 = [[NSDateComponents alloc] init];
[compt4 setYear:2012];
[compt4 setMonth:5];
[compt4 setDay:11];
//NSDateComponents对象转NSDate对象
NSDate *newDate = [calendar dateFromComponents:compt4];
//得到本地时间,避免时区问题
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger interval = [zone secondsFromGMTForDate:newDate];
NSDate *localeDate = [newDate dateByAddingTimeInterval:interval];
NSLog(@"NSDateComponents对象转NSDate对象:%@",localeDate);
/*********************************************************************/
//创建自定义NSDateComponents对象
NSDateComponents *compt5 = [[NSDateComponents alloc] init];
[compt5 setDay:25];
[compt5 setHour:4];
[compt5 setMinute:66];
NSDate *addDate = [calendar dateByAddingComponents:compt5
                                            toDate:[NSDate date]
                                           options:0];
//得到本地时间,避免时区问题
NSTimeZone *zone2 = [NSTimeZone systemTimeZone];
NSInteger interval2 = [zone2 secondsFromGMTForDate:addDate];
NSDate *localeDate2 = [addDate dateByAddingTimeInterval:interval2];
NSLog(@"NSDate对象追加NSDateComponents对象时间:%@",localeDate2);
NSCalendar类还有一些日历设置和计算的方法:
/* 设置本地化信息 */
- (void)setLocale:(NSLocale *)locale;
/* 设置时区信息 */
- (void)setTimeZone:(NSTimeZone *)tz;
/* 设置每周的第一天是从星期几开始,1表示是星期天(默认),2表示星期一,以此类推 */
- (void)setFirstWeekday:(NSUInteger)weekday;
/* 设置每年及每月第一周必须包含的最少天数,比如:设定第一周最少包括3天,则value传入3 */
- (void)setMinimumDaysInFirstWeek:(NSUInteger)value;
/* 获取一个小的单位在一个大的单位里面的序数 */
- (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller
                        inUnit:(NSCalendarUnit)larger
                       forDate:(NSDate *)date;
/* 根据参数提供的时间点,得到一个小的单位在一个大的单位里面的取值范围 */
- (NSRange)rangeOfUnit:(NSCalendarUnit)smaller
                inUnit:(NSCalendarUnit)larger
               forDate:(NSDate *)date;
/*
  根据参数提供的时间点,返回所在日历单位的开始时间。
  如果startDate和interval都计算得出来,则返回YES;否则返回NO
 */
- (BOOL)rangeOfUnit:(NSCalendarUnit)unit  /* 日历单位 */
          startDate:(NSDate **)datep /* 开始时间,通过参数返回 */
           interval:(NSTimeInterval *)tip /* 日历单位所对应的秒数,通过参数返回 */
            forDate:(NSDate *)date; /* 时间点参数 */

七、NSDateFormatter字符串格式化

NSDateFormatter专门负责时间NSDate和字符串NSString之间的转换

下面是格式化符使用规定:
  • 大写G:纪元

    一般会显示公元前(BC)和公元(AD)

  • 小写y:年

    假如是2013年,那么yyyy=2013,yy=13

  • 大写M:月

    假如是3月,那么M=3,MM=03,MMM=Mar,MMMM=March

    假如是11月,那么M=11,MM=11,MMM=Nov,MMMM=November

  • 小写w:年包含的周

    假如是1月8日,那么w=2(这一年的第二个周)

  • 大写W:月份包含的周(与日历排列有关)

    假如是2013年4月21日,那么W=4(这个月的第四个周)

  • 大写F:月份包含的周(与日历排列无关)

    和上面的W不一样,F只是单纯以7天为一个单位来统计周,例如7号一定是第一个周,15号一定是第三个周,与日历排列无关。

  • 大写D:年包含的天数

    假如是1月20日,那么D=20(这一年的第20天)

    假如是2月25日,那么D=31+25=56(这一年的第56天)

  • 小写d:月份包含的天数

    假如是5号,那么d=5,dd=05

    假如是15号,那么d=15,dd=15

  • 大写E:星期

    假如是星期五,那么E=Fri,EEEE=Friday

  • 小写a:上午(AM)/下午(PM)
  • 大写H:24小时制,显示为0–23

    假如是午夜00:40,那么H=0:40,HH=00:40

  • 小写h:12小时制,显示为1–12

    假如是午夜00:40,那么h=12:40

  • 大写K:12小时制,显示为0–11

    假如是午夜00:40,那么K=0:40,KK=00:40

  • 小写k:24小时制,显示为1–24

    假如是午夜00:40,那么k=24:40

  • 小写m:分钟

    假如是5分钟,那么m=5,mm=05

    假如是45分钟,那么m=45,mm=45

  • 小写s:秒

    假如是5秒钟,那么s=5,ss=05

    假如是45秒钟,那么s=45,ss=45

  • 大写S:毫秒

    一般用SSS来显示

  • 小写z:时区

    表现形式为GMT+08:00

  • 大写Z:时区

    表现形式为+0800

下面是使用范例:
//创建日期字符串格式化器
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//设置时区
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
//设置格式化输出格式
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];
//创建时间
NSDateComponents *compt = [[NSDateComponents alloc] init];
[compt setYear:2013];
[compt setMonth:3];
[compt setDay:13];
[compt setHour:1];
[compt setMinute:55];
[compt setSecond:28];
//获取日历对象
NSCalendar *calendar = [NSCalendar currentCalendar];
//设置时区
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
//NSDateComponents对象转NSDate对象
NSDate *date = [calendar dateFromComponents:compt];
NSLog(@"date:%@",date);
//格式化输出字符串,传入要格式化的时间NSDate对象
NSString *str = [formatter stringFromDate:date];
NSLog(@"格式化输出:%@",str);
详细介绍可以参考这里,讲得很详细:wayne23的博客
如果有什么问题可以在下方评论区中提出!O(∩_∩)O哈!
时间: 2024-10-12 22:48:36

iOS学习笔记37-时间和日期计算的相关文章

IOS学习笔记37——ViewController生命周期详解

在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它.ViewController是IOS开发中MVC模式中的C,ViewController是view的controller,ViewController的职责主要包括管理内部各个view的加载显示和卸载,同时负责与其他ViewController的通信和协调.在IOS中,有两类ViewController,一类是显示内容

javascript学习笔记之时间与日期

1.Date类型 js提供Date类型来处理日期和时间 <script type="text/javascript">         var date = new Date();         document.writeln(date);         //Thu Jan 08 2015 01:25:53 GMT+0800 (中国标准时间)         document.writeln(Date.parse());         //NaN         d

iOS学习笔记(2)— UIView用户事件响应

iOS学习笔记(2)— UIView用户事件响应 UIView除了负责展示内容给用户外还负责响应用户事件.本章主要介绍UIView用户交互相关的属性和方法. 1.交互相关的属性 userInteractionEnabled 默认是YES ,如果设置为NO则不响应用户事件,并且把当前控件从事件队列中删除.也就是说设置了userInterfaceEnabled属性的视图会打断响应者链导致该view的subview都无法响应事件. multipleTouchEnabled  默认是NO,如果设置为YE

iOS学习笔记-精华整理

iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始等待用户的操作,自动释放池就会被释放掉(调用dealloc),池中的对象都会收到一个release,有可能会因此被销毁. 2-成员属性:     readonly:不指定readonly,默认合成getter和setter方法.外界毫不关心的成员,则不要设置任何属性,这样封装能增加代码的独立性和安全

iOS学习笔记---oc语言第七天

类的扩展 NSDate是Cocoa中用于处理日期和时间的基础类,封装了某一给定的时刻,具体的日期 时间和时区 使用+date方法获取当前日期和时间 1 NSDate *date = [NSDate date];//获取当前时间 2 NSLog(@"%@",date);//无论你是哪个时区的时间,打印的总是o时区的时间 3 NSDate *date2 = [NSDate dateWithTimeIntervalSinceNow:60*60*8];//从现在开始之后的时间 4 NSLog(

iOS学习笔记---c语言第十一天

函数指针 一.函数指针定义 //函数声明:声明我是一个什么函数 //求两个数的和 //函数的类型:int (int x,int y) //即:我是一个返回值为整型,有两个整型参数的函数. //函数名是 sum int sum(int x,int y); 函数指针定义p是变量,其他是类型(通常没有形参a,b) //函数指针类型 int (*)(int x,int y) //描述:指向 返回值为 int 两个int参数 的 指针类型 //函数指针变量: p //初始值 : sum printf("%

iOS学习笔记之UITableViewController&amp;UITableView

iOS学习笔记之UITableViewController&UITableView 写在前面 上个月末到现在一直都在忙实验室的事情,与导师讨论之后,发现目前在实验室完成的工作还不足以写成毕业论文,因此需要继续思考新的算法.这是一件挺痛苦的事情,特别是在很难找到与自己研究方向相关的文献的时候.也许网格序列水印这个课题本身的研究意义就是有待考证的.尽管如此,还是要努力的思考下去.由于实验室的原因,iOS的学习进度明显受到影响,加之整理文档本身是一件耗费时间和精力的事情,因此才这么久没有写笔记了. M

IOS学习笔记 -- Modal和Quartz2D

一. Modal1.Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止;Modal只是改变了View的现实,没有改变rootViewController 2.常用方法1>.以Modal的形式展示控制器- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion2>.关

iOS学习笔记(1)— UIView 渲染和内容管理

iOS学习笔记(1)— UIView 渲染和内容管理 iOS中应用程序基本上都是基于MVC模式开发的.UIView就是模型-视图-控制器中的视图,在iOS终端上看到的.摸到的都是UIView. UIView在屏幕上定义了一个矩形区域和管理区域内容的接口.在运行时,一个视图对象控制该区域的渲染:UIView继承自UIResponder,UIResponder是用来响应事件的类,UIView也具有响应事件的能力.所以说UIView具有三个基本的功能,绘制内容并管理内容的布局,响应用户交互,动画.正是