OC Foundation框架 日期与时间
Posted Billy Miracle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OC Foundation框架 日期与时间相关的知识,希望对你有一定的参考价值。
OC为处理日期、时间提供了NSDate、NSCalendar对象,还提供了日期格式器来处理日期与字符串之间的转换。
日期与时间(NSDate)
下面通过一个程序来介绍NSDate类的常见方法的用途
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
//获取当前日期、时间的NSDate
NSDate* date1 = [NSDate date];
NSLog(@"%@", date1);
//获取从当前时间开始,一天之后的日期
NSDate* date2 = [[NSDate alloc] initWithTimeIntervalSinceNow: 3600*24];
NSLog(@"%@", date2);
//获取从当前时间开始,3天之前的日期
NSDate* date3 = [[NSDate alloc] initWithTimeIntervalSinceNow: -3*3600*24];
NSLog(@"%@", date3);
//获取从1970年1月1日开始,20年后的日期
NSDate* date4 = [[NSDate alloc] initWithTimeIntervalSince1970: 3600*24*366*20];
NSLog(@"%@", date4);
//获取系统当前的NSLocale
NSLocale* cn = [NSLocale currentLocale];
//获取NSDate在当前NSLocale下对应的字符串
NSLog(@"%@", [date1 descriptionWithLocale: cn]);
//获取两个日期之间较早的日期
NSDate* earlier = [date1 earlierDate: date2];
//获取两个日期之间较晚的日期
NSDate* later = [date1 laterDate: date2];
NSLog(@"%@ < %@", earlier, later);
//比较两个日期,compare: 方法返回NSComparisonResult枚举值
//该枚举类型包含NSOrderedAscending、NSOrderedSame和
//NSOrderedDescending三个值
//分别代表调用compare: 的日期位于被比较日期之前、相同、之后
switch ([date1 compare: date3]) {
case NSOrderedAscending:
NSLog(@"dete1位于date3之前");
break;
case NSOrderedSame:
NSLog(@"date1与date3日期相等");
break;
case NSOrderedDescending:
NSLog(@"dete1位于date3之后");
break;
}
//获取两个时间之间的时间差
NSLog(@"date1与date3之间时间差%g秒",[date1 timeIntervalSinceDate: date3]);
//获取指定时间与现在时间差
NSLog(@"date2与现在时间差%g秒", [date2 timeIntervalSinceNow]);
}
return 0;
}
可以看出,创建NSDate的类方法与实例方法基本相似,只是类方法以date开头,而实例方法以init开头。
输出:
Wed Jun 2 15:15:59 2021
Thu Jun 3 15:15:59 2021
Sun May 30 15:15:59 2021
Tue Jan 16 08:00:00 1990
2021年6月2日 星期三 中国标准时间 下午3:15:59
Wed Jun 2 15:15:59 2021 < Thu Jun 3 15:15:59 2021
dete1位于date3之后
date1与date3之间时间差259200秒
date2与现在时间差86400秒
日期格式器(NSDateFormatter)
NSDateFormatter代表一个日期格式器,它的功能就是完成NSDate与NSString之间的转换。
转换步骤:
- 创建一个NSDateFormatter对象
- 调用NSDateFormatter的setDateStyle:、 setTimeStyle:方法设置格式化日期、时间的风格。其中,日期、时间风格支持如下几个枚举值。
- NSDateFormatterNoStyle:不显示日期、时间的风格
- NSDateFormatterShortStyle:显示短的日期、时间风格
- NSDateFormatterMediumStyle:显示中等的日期、时间风格
- NSDateFormatterLongStyle:显示长的日期、时间风格
- NSDateFormatterFullStyle:显示完整的日期、时间风格
如果打算使用自己的格式模版,则调用NSDateFormatter的setDateFormat: 方法设置日期、时间的模版即可。
- 如果需要将NSDate转换为NSString,则调用NSDateFormatter的stringFromDate: 方法执行格式化即可;如果需要将NSString转换为NSDate,则调用NSDateFormatter的dateFromString: 方法执行格式化即可。
示例:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
//需要被格式化的时间
//获取现在的时间或者从1970年1月1日开始,20年后的日期
//NSDate* dt = [NSDate dateWithTimeIntervalSince1970: 3600*24*366*20];
NSDate* dt = [NSDate date];
//创建两个NSLocale,分别代表中国、美国
NSLocale* locales[] = {[[NSLocale alloc] initWithLocaleIdentifier: @"zh_CN"] , [[NSLocale alloc] initWithLocaleIdentifier: @"en_US"]};
NSDateFormatter* df[8];
//为上面两个NSLocale创建8个NSDateFormatter对象
for (int i = 0; i < 2; ++i) {
df[i * 4] = [[NSDateFormatter alloc] init];
//设置NSDateFormatter的日期、时间风格
[df[i * 4] setDateStyle: NSDateFormatterShortStyle];
[df[i * 4] setTimeStyle: NSDateFormatterShortStyle];
//设置NSDateFormatter的NSLocale
[df[i * 4] setLocale: locales[i]];
df[i * 4 + 1] = [[NSDateFormatter alloc] init];
//设置NSDateFormatter的日期、时间风格
[df[i * 4 + 1] setDateStyle: NSDateFormatterMediumStyle];
[df[i * 4 + 1] setTimeStyle: NSDateFormatterMediumStyle];
//设置NSDateFormatter的NSLocale
[df[i * 4 + 1] setLocale: locales[i]];
df[i * 4 + 2] = [[NSDateFormatter alloc] init];
//设置NSDateFormatter的日期、时间风格
[df[i * 4 + 2] setDateStyle: NSDateFormatterLongStyle];
[df[i * 4 + 2] setTimeStyle: NSDateFormatterLongStyle];
//设置NSDateFormatter的NSLocale
[df[i * 4 + 2] setLocale: locales[i]];
df[i * 4 + 3] = [[NSDateFormatter alloc] init];
//设置NSDateFormatter的日期、时间风格
[df[i * 4 + 3] setDateStyle: NSDateFormatterFullStyle];
[df[i * 4 + 3] setTimeStyle: NSDateFormatterFullStyle];
//设置NSDateFormatter的NSLocale
[df[i * 4 + 3] setLocale: locales[i]];
}
for (int i = 0; i < 2; ++i) {
switch (i) {
case 0:
NSLog(@"------------中国日期格式------------");
break;
case 1:
NSLog(@"------------美国日期格式------------");
break;
}
NSLog(@"SHORT格式的日期格式:%@", [df[i * 4] stringFromDate: dt]);
NSLog(@"MEDIUM格式的日期格式:%@", [df[i * 4 + 1] stringFromDate: dt]);
NSLog(@"LONG格式的日期格式:%@", [df[i * 4 + 2] stringFromDate: dt]);
NSLog(@"FULL格式的日期格式:%@", [df[i * 4 + 3] stringFromDate: dt]);
}
NSDateFormatter* df2 = [[NSDateFormatter alloc] init];
//设置自定义的格式模版
[df2 setDateFormat:@"公元 yyyy 年 MM 月 DD 日 HH 时 mm 分"];
//执行格式化
NSLog(@"%@" , [df2 stringFromDate: dt]);
NSString* dateStr = @"2021-06-01";
NSDateFormatter* df3 = [[NSDateFormatter alloc] init];
//根据日期字符串的格式设置格式模版
[df3 setDateFormat: @"yyyy-MM-dd"];
//将字符串转换为NSDate对象
NSDate* date2 = [df3 dateFromString: dateStr];
NSLog(@"%@" , date2);
}
return 0;
}
输出结果:
日历(NSCalendar)与日期组件(NSDateComponents)
为了能分开处理NSDate对象所包含的各个字段的数据,Foundation框架提供了NSCalendar对象,该对象包含如下两个常用方法。
- (NSDateComponents*)components:fromDate: :从NSDate中提取年、月、日、时、分、秒各时间字段的信息。
- dateFromComponents:(NSDateComponents*)comps :使用comps对象包含的年、月、日、时、分、秒各时间字段的信息来创建NSDate。
从NSDate对象中分开获取各时间字段的数值的步骤如下:
- 创建NSCalendar对象
- 调用NSCalendar的components: fromDate: 方法获取NSDate对象中各时间字段的数值,该方法返回一个NSDateComponents对象。
- 调用NSDateComponents对象的getter方法来获取各时间字段的数值。
使用各时间字段的数值来初始化NSDate对象的步骤如下:
- 创建NSCalendar对象
- 创建一个NSDateComponents对象,调用该对象的setter方法来设置各时间字段的数值
- 调用NSCalendar的dateFromComponents:(NSDateComponents*)方法初始化NSDate对象,该方法会返回一个NSDate对象。
示例:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
//获取代表公历的NSCalendar对象
NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSCalendarIdentifierGregorian];
//获取当前日期
NSDate* dt =[NSDate date];
//定义一个时间字段的旗标,指定会获取指定年、月、日、时、分、秒、星期的信息
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday;
//获取不同时间字段的信息
NSDateComponents* comp = [gregorian components: unitFlags fromDate: dt];
//获取各时间字段的数值
NSLog(@"现在是%ld年", comp.year);
NSLog(@"现在是%ld月", comp.month);
NSLog(@"现在是%ld日", comp.day);
NSLog(@"现在是%ld时", comp.hour);
NSLog(@"现在是%ld分", comp.minute);
NSLog(@"现在是%ld秒", comp.second);
NSLog(@"现在是星期%ld", comp.weekday);
//再次创建一个NSDateComponents对象
NSDateComponents* comp2 = [[NSDateComponents alloc] init];
//设置各时间段的数值
comp2.year = 2021;
comp2.month = 6;
comp2.day = 1;
comp2.hour = 10;
comp2.minute = 23;
//通过NSDateComponents所包含的各时间字段的数值来恢复NSDate对象
NSDate* date = [gregorian dateFromComponents: comp2];
NSLog(@"获取的日期为%@", date);
}
return 0;
}
输出结果:
定时器(NSTimer)
如果程序需要让某个方法重复执行,则可以借助OC的定时器来完成。具体步骤如下:
- 调用NSTimer的scheduledTimerWithTimeInterval:invonation:repeats: 或scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 类方法来创建NSTimer对象。调用该类方法时,需要传入以下参数:
- timeInterval:指定每隔多少秒执行一次任务。
- invocation或target与selector:指定重复执行的任务。如果指定target和selector参数,则指定用某个对象的特定方法作为重复执行任务;如果指定invocation参数,该参数需要传入一个NSInvocation对象,该NSInvocation对象也是封装target和selector的,其实也是指定某个对象的特定方法作为重复执行的任务。
- userInfo:该参数用于传入额外的附加信息。
- repeats:该参数需要指定一个BOOL值,该参数控制是否需要重复执行任务。
- 为第一步的任务编写方法。
- 销毁定时器。调用定时器的invalidate方法即可。
示例:
// Timer.h
#import <Foundation/Foundation.h>
@interface Timer : NSObject {
NSInteger _index;
NSTimer* _timer;
}
-(void) startMyTimer;
-(void) stopMyTimer;
-(void)timerAction: (NSTimer*) timer;
@end
// Timer.m
#import "Timer.h"
@implementation Timer
- (instancetype)init {
if (self = [super init]) {
_index = 10;
[self startMyTimer];
}
return self;
}
- (void)startMyTimer {
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(timerAction:)
userInfo:@"hello."
repeats:YES];
}
- (void)stopMyTimer {
[_timer invalidate];
NSLog(@"倒计时结束");
}
- (void)timerAction:(NSTimer *)timer {
_index--;
NSLog(@"%li秒",_index);
NSLog(@"%@",timer.userInfo);
if (_index == 0) {
[self stopMyTimer];
}
}
@end
// main.m
#import "Timer.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Timer* mytimer = [[Timer alloc] init];
NSRunLoop *loop = [NSRunLoop currentRunLoop];
[loop run];
}
return 0;
}
最后执行程序,每秒输出一次:
以上是关于OC Foundation框架 日期与时间的主要内容,如果未能解决你的问题,请参考以下文章