OC学习记录,日期与时间

日期与时间(NSDate)

NSDate对象代表日期和时间。Objective-C既提供了类方法来创建NSDate对象,也提供了大量以init开头的方法来初始化NSDate对象。关于NSDate类各个方法,可以参考NSDate的参考文档。下面通过示例程序介绍NSDate类的常见方法的用途。

#import<Foundation/Foundation.h>

int main(int argc, 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 dateWithTimeIntervalSince1970: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];
        //比较两个日期,compare:  方法返回NSComparisonResult枚举值
        //该枚举类型包含NSOrderedAscending、NSOrderedSame和
        //NSOrderedDescending三个值
        //分别代表调用compare:的日期位于被比较日期之前、相同、之后
        switch([date1 compare:date3]){
            case NSOrderedAscending:
                NSLog(@"date1位于date3之前");
                break;
            case NSOrderedSame:
                NSLog(@"date1与date3日期相等");
                break;
            case NSOrderedDescending:
                NSLog(@"date1位于date3之后");
                break;
        }
        //获取两个时间之间的时间差
        NSLog(@"date1与date3之间时间差%g秒", [date1 timeIntervalSinceDate:date3]);
        //获取指定时间与现在时间差
        NSLog(@"date2与现在时间差%g秒", [date2 timeIntervalSinceNow]);
    }
    return 0;
}

从上面的代码可以看出,创建NSDate的类方法与实例方法基本类似,只是类方法以date开头而实例方法以init开头。一旦得到NSDate对象,两个NSDate之间就可以比较大小,可以计算两个NSDate之间的时间差,也可以把NSDate转换为符合当前NSLocale的格式字符串。
在这里插入图片描述
编译、运行后,可看到如下输出:

2022-05-29 20:33:00.641475+0800 练习[29683:1288641] Sun May 29 20:33:00 2022
2022-05-29 20:33:00.641600+0800 练习[29683:1288641] Mon May 30 20:33:00 2022
2022-05-29 20:33:00.641620+0800 练习[29683:1288641] Thu May 26 20:33:00 2022
2022-05-29 20:33:00.641639+0800 练习[29683:1288641] Tue Jan 16 08:00:00 1990
2022-05-29 20:33:00.649731+0800 练习[29683:1288641] 2022年5月29日 星期日 中国标准时间 下午8:33:00
2022-05-29 20:33:00.649774+0800 练习[29683:1288641] date1位于date3之后
2022-05-29 20:33:00.649795+0800 练习[29683:1288641] date1与date3之间时间差259200秒
2022-05-29 20:33:00.649810+0800 练习[29683:1288641] date2与现在时间差86400秒
Program ended with exit code: 0

日期格式器(NSDateFormatter)

NSDateFormatter代表一个日期格式器,他的功能就是完成NSDate与NSString之间的转换。
使用NSDateFormatter完成NSDate与NSString之间转换的步骤如下。

  1. 创建一个NSDateFormatter对象。
  2. 调用NSDateFormatetr的setDateStyle:、setTimeStyle:方法设置格式化日期、时间的风格。其中,日期、风格支持如下几个枚举值。
  • NSDateFormatterNoStyle:不显示日期、时间的风格。
  • NSDateFormatterShortStyle:显示“短”的日期、时间风格。
  • NSDateFormatterMediiumStyle:显示“中等”的日期、时间风格。
  • NSDateFormatterLongStyle:显示“长”的日期、时间风格。
  • NSDateFormatterFullStyle:显示“完整”的日期、时间风格。
    如果打算使用自己的格式模板,则调用NSDateFormatter的setDFateFormat:方法设置日期、时间的模板即可。
  1. 如果需要将NSDate转换为NSString,则调用NSDateFormatter的stringFromDate:方法执行格式化即可;如果需要将NSString转换为NSDate,则调用NSDateFormatter的dataFromString:方法执行格式化即可。
    如下程序示范了NSDateFormatter的功能和用法。
#import<Foundation/Foundation.h>

int main(int argc, char * argv[]) {
    @autoreleasepool{
        //获取被格式化的时间
        //获取从1970年1月1日开始,20年之后的日期
        NSDate* dt = [NSDate dateWithTimeIntervalSince1970:3600 * 24 * 366 * 20];
        //创建两个NSLocale,分别代表中国、美国
        NSLocale* locale[] = {
            [[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: locale[i]];
            df[i * 4 + 1] = [[NSDateFormatter alloc] init];
            
            // 设置NSDateFormatter的日期、时间风格
            [df[i * 4 + 1] setDateStyle: NSDateFormatterShortStyle];
            [df[i * 4 + 1] setTimeStyle: NSDateFormatterShortStyle];
            //设置NSDateFormatter的NSLocale
            [df[i * 4 + 1] setLocale: locale[i]];
            df[i * 4 + 2] = [[NSDateFormatter alloc] init];
            
            // 设置NSDateFormatter的日期、时间风格
            [df[i * 4 + 2] setDateStyle: NSDateFormatterShortStyle];
            [df[i * 4 + 2] setTimeStyle: NSDateFormatterShortStyle];
            //设置NSDateFormatter的NSLocale
            [df[i * 4 + 2] setLocale: locale[i]];
            df[i * 4 + 3] = [[NSDateFormatter alloc] init];
            
            // 设置NSDateFormatter的日期、时间风格
            [df[i * 4 + 3] setDateStyle: NSDateFormatterShortStyle];
            [df[i * 4 + 3] setTimeStyle: NSDateFormatterShortStyle];
            //设置NSDateFormatter的NSLocale
            [df[i * 4 + 3] setLocale: locale[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 = @"2013-03-02";
        NSDateFormatter* df3 = [[NSDateFormatter alloc] init];
        // 根据日期字符串的格式设置格式模板
        [df3 setDateFormat:@"yyyy-MM-dd"];
        //将字符串转换为NSDate对象
        NSDate* date2 = [df3 dateFromString: dateStr];
        NSLog(@"%@", date2);
    }
    return 0;
}

从上面的代码可以看出,创建NSDate的类方法与实例方法基本类似,只是类方法以date开头,而实例方法以init开头。一旦得到NSDate对象,两个NSDate之间就可以比较大小,可以计算两个NSDate之间的时间差,也可以把NSDate转换为符合当前NSLocale的格式字符串。
在这里插入图片描述
编译运行该程序,可以看到如下输出:

2022-05-31 19:38:49.226363+0800 练习[51468:2180178] -------中国日期格式-------
2022-05-31 19:38:49.239758+0800 练习[51468:2180178] SHORT格式的日期格式:1990/1/16 上午8:00
2022-05-31 19:38:49.239914+0800 练习[51468:2180178] MEDIUM格式的日期格式:1990/1/16 上午8:00
2022-05-31 19:38:49.240017+0800 练习[51468:2180178] LONG格式的日期格式:1990/1/16 上午8:00
2022-05-31 19:38:49.240111+0800 练习[51468:2180178] FULL格式的日期格式:1990/1/16 上午8:00
2022-05-31 19:38:49.240131+0800 练习[51468:2180178] -------美国日期格式-------
2022-05-31 19:38:49.240450+0800 练习[51468:2180178] SHORT格式的日期格式:1/16/90, 8:00 AM
2022-05-31 19:38:49.240604+0800 练习[51468:2180178] MEDIUM格式的日期格式:1/16/90, 8:00 AM
2022-05-31 19:38:49.240731+0800 练习[51468:2180178] LONG格式的日期格式:1/16/90, 8:00 AM
2022-05-31 19:38:49.240856+0800 练习[51468:2180178] FULL格式的日期格式:1/16/90, 8:00 AM
2022-05-31 19:38:49.242872+0800 练习[51468:2180178] 公元1990年01月16日 08时 00分
2022-05-31 19:38:49.243773+0800 练习[51468:2180178] Sat Mar 2 00:00:00 2013
Program ended with exit code: 0

上面程序示范了如何完成NSDate与NSString之间的转换,并分别示范了在美式英语环境和简体中文环境下将NSDate转换为NSString的效果。

日历(NSCalendar)与日期组件(NSDateComponents)

前面介绍了NSDate的功能和用法,以及NSDate与NSString之间的相互转换。假如有如下场景:程序提供了3个输入框,让用户分别输入年、月、日的数值,接下来需要将年、月、日数值转换为NSDate;另一个场景:得到一个NSDate对象之后,程序需要获取该NSDate中包含的年份、月份、第几日。这些都需要将NSDate对象的各个字段数据分开提取。
为了能分开处理NSDate对象所包含的各个字段的数据,Foundation框架提供了NSCalendar对象,该对象包含如下两个常用方法。

  • (NSDateComponents*)components:from:Date:从NSDate中提取年、月、日、时、分、秒各时间字段的信息。
  • dateFromComponents:(NSDateComponents*)comps:使用comps:对象包含的年、月、日、时、分、秒各时间字段的信息来创建NSDate。
    上面两个方法都用到一个NSDateComponents对象,该对象专门用于封装年、月、日、时、分、秒各时间字段的信息。该对象非常简单,它只包含了对year、month、date、day、hour、minute、second、week、weekday等各字段的setter和getter方法。

在这里插入图片描述
下面示范了如何利用NSCalendar和NSDateComponents分开处理NSDate中各时间字段的数值。

#import<Foundation/Foundation.h>

int main(int argc, 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);
        //再次创建一个NSDateComponts对象
        NSDateComponents* comp2 = [[NSDateComponents alloc] init];
        //设置各时间字段的数值
        comp2.year = 2013;
        comp2.month = 4;
        comp2.day = 5;
        comp2.hour = 18;
        comp2.minute = 34;
        //通过NSDateComponents所包含各时间字段的数值来恢复NSDate对象
        NSDate * date = [gregorian dateFromComponents:comp2];
        NSLog(@"获取的日期为:%@", date);
    }
    return 0;
}

在上面的程序中,第一行代码示范了从NSDate对象中获取个时间字段的数值;第二行粗体字代码示范了如何利用各时间字段的数值来初始化NSDate对象。
编译、运行该程序,可以看到如图所示结果。

2022-05-31 21:19:46.656723+0800 练习[52394:2228931] 现在是2022年
2022-05-31 21:19:46.656904+0800 练习[52394:2228931] 现在是5月
2022-05-31 21:19:46.656928+0800 练习[52394:2228931] 现在是31日
2022-05-31 21:19:46.656945+0800 练习[52394:2228931] 现在是21时
2022-05-31 21:19:46.656958+0800 练习[52394:2228931] 现在是19分
2022-05-31 21:19:46.656970+0800 练习[52394:2228931] 现在是46秒
2022-05-31 21:19:46.656983+0800 练习[52394:2228931] 现在是星期3
2022-05-31 21:19:46.662194+0800 练习[52394:2228931] 获取的日期为:2013-04-05 10:34:00 +0000
Program ended with exit code: 0

定时器(NSTimer)

如果程序需要让某个方法重复执行,则可以借助Objective-C的定时器来完成。使用Objective-C的定时器编程很简单,具体步骤如下。

  1. 调用NSTimer的scheduledTimerWithTimeInterval:invocation:repeats:或scheduleTimerWithTimeInterval:target:selector:userInfo:repeats:类方法来创建NSTimer对象。调用该类方法时,需要传入如下参数。
  • timeInterval:指定每隔多少秒执行一次任务。
  • invocation或target与selector:指定重复执行的任务。如果指定target和selector参数,则指定用某个对象的特定方法作为重复执行的任务;如果指定invocation参数,该参数需要传入英国NSInvocation对象,该NSInvocation对象也是封装target和selector的,其实也是指定某个对象的特定方法作为重复执行的任务/
    userInfo: 该参数用于传入额外的附加信息。
    repeats:该参数需要指定一个BOOL值,该参数控制是否需要重复执行任务
  1. 为第1步的任务编写方法。
  2. 销毁定时器。调用定时器的invalidate方法即可。
    为了测定定时器的作用,此处将前面介绍的DelegateTest应用进行一些修改。在应用加载时启动一个定时器。
    在该应用的委托类FKAppDelegate中applicationWillFinishLaunching:方法的最后增加如下代码。
_timer = [NSTimer scheduleTimeWithTimeInterval:0.5
target:self//指定以当前对象的info:方法作为执行任务
selector:@selector(info:)
userInfo:nil
repeats:YES];//指定重复执行

上面代码中指定以当前对象的info:方法作为任务执行体,因此,程序还需要在该类中定义一个info:方法,该方法可定义一个NSTimer参数,该参数代表调度该任务的定时器。
增加的info:方法代码如下。

-void) info:(NSTimer*) timer {
	NSLog(@"正在执行第%ld次任务", _count++);
	//如果_count的值大于10,则取消定时器
	if(_count > 10) {
		NSLog(@"取消执行定时器");
		[_timer invalidate];
	}
}

上面info:方法的代码很简单,该方法只是在控制台简单的打印一行,接着程序判断如果_count的值大于10,就取消_timer对象。
上面程序中还用到了_timer、_count两个成员变量,因此还需要在FKAppDelegate.m中额外定义这两个成员变量,其代码如下:

NSInteger _count;
NSTimer* _timer;

完成上面例子之后,运行该程序,当程序加载完成后,就会启动一个定时器,该定时器就会控制程序的info:方法执行11次。运行该程序,可以看到如图7.3所示的输出。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值