obj-c编程10:Foundation库中类的使用(5)[时间对象]

隔了好久才有了这新的一篇,还是无奈的时间啊!so这次我们就着重谈谈它喽。

F库中有很多时间相关的类,比如NSDate,NSTimeInterval,NSTimeZone,NSDateComponents,NSCalendar,最后还有一个NSDateFormatter。新手很快就被弄的云里雾里了,我也在雾里呆了好长段时间了。简单地说NSDate只是一个单纯的时间类;NSTimeInterval用来表示2个时间之间的间隔;NSTimeZone和NSCalendar顾名思义自然是表示时区和日历啦;NSDateComponents可以从多个单个元素构建任意一个时间,而NSDateFormatter可以将时间转换为一个人类可读的字符串或者反向转换。下面我们用代码来说明问题喽:

#import <Foundation/Foundation.h>

//static int g_idx = 0;

#define msg(...) printf("[[%d]]:\n",__LINE__);NSLog(__VA_ARGS__)

int main(int argc,char *argv[])
{
	@autoreleasepool{
		//创建现在时间的NSDate对象
		NSDate *now = [NSDate date];
		NSDate *now_too = [[NSDate alloc] init];
		msg(@"now is %@ and %@",now,now_too);

		//使用时间间隔创建NSDate对象
		NSDate *now_sub_hour = [now dateByAddingTimeInterval:-3600];
		NSDate *now_add_hour = [now dateByAddingTimeInterval:3600];
		msg(@"now +- hour is %@ and %@",now_add_hour,now_sub_hour);

		//计算2个时间的间隔(以秒计)
		NSTimeInterval interval1 = [now timeIntervalSinceDate:now_sub_hour];
		NSTimeInterval interval2 = [now timeIntervalSinceDate:now_add_hour];
		msg(@"intervals is %f and %f",interval1,interval2);

		//比较2个时间的“大小”
		assert([now laterDate:now_add_hour] == now_add_hour);	//true
		assert([now earlierDate:now_sub_hour] == now_sub_hour);	//true
		assert([now compare:now_sub_hour] == NSOrderedDescending);	//true

		NSTimeZone *zone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];

		//使用时间组件对象和日历对象构造时间
		NSDateComponents *cps = [[NSDateComponents alloc] init];
		[cps setTimeZone:zone];

		[cps setMonth:11];
		[cps setDay:23];
		[cps setYear:2018];
		[cps setHour:23];
		[cps setMinute:59];
		[cps setSecond:31];
		NSCalendar *calar = [NSCalendar currentCalendar];
		NSDate *date = [calar dateFromComponents:cps];
		msg(@"date is %@",date);
		[cps setDay:([cps day] - 1)];
		[cps setMinute:([cps minute] + 1)];
		date = [calar dateFromComponents:cps];
		msg(@"date is %@",date);

		//设置日历类型为中国日历类型
		NSCalendar *china_calar = [[NSCalendar alloc] initWithCalendarIdentifier:\
			NSRepublicOfChinaCalendar];
		date = [china_calar dateFromComponents:cps];
		msg(@"china_calar style is %@",date);

		//列出所有已知时区
		//msg(@"all zone :\n%@",[NSTimeZone knownTimeZoneNames]);
		//在时间对象中考虑时区因素
		msg(@"时区缩写:%@",[zone abbreviation]);
		NSData *data = [zone data];
		msg(@"time data is %@",data);
		NSCalendar *calar_zone = [NSCalendar currentCalendar];
		[calar_zone setTimeZone:zone];
		cps = [calar_zone components:(NSYearCalendarUnit|NSMonthCalendarUnit|\
			NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|\
			NSSecondCalendarUnit) fromDate:now];
		[cps setTimeZone:zone];
		date = [calar_zone dateFromComponents:cps];
		msg(@"time with zone : %@",date);

		NSDateFormatter *f = [[NSDateFormatter alloc]init];
		[f setDateFormat:@"yyyy-MM-dd hh:mm:ss"];

		msg(@"init time_zone is %@",[f timeZone]);
		date = [f dateFromString:@"2019-10-11 03:14:59"];
		msg(@"date is %@",date);
		[f setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
		date = [f dateFromString:@"2019-10-11 03:14:59"];
		msg(@"date is %@",date);
		[f setTimeZone:[NSTimeZone timeZoneWithName:@"GMT+8"]];
		NSString *fix_date_str = [f stringFromDate:date];
		msg(@"fix_str is %@",fix_date_str);
		[f setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
		date = [f dateFromString:fix_date_str];
		msg(@"date is %@",date);
	}
	return 0;
}

编译执行结果如下:

apple@kissAir: objc_src$./8

[[13]]:

2014-07-20 17:42:03.593 8[2468:507] now is 2014-07-20 09:42:03 +0000 and 2014-07-20 09:42:03 +0000

[[18]]:

2014-07-20 17:42:03.594 8[2468:507] now +- hour is 2014-07-20 10:42:03 +0000 and 2014-07-20 08:42:03 +0000

[[23]]:

2014-07-20 17:42:03.594 8[2468:507] intervals is 3600.000000 and -3600.000000

[[44]]:

2014-07-20 17:42:03.595 8[2468:507] date is 2018-11-23 15:59:31 +0000

[[48]]:

2014-07-20 17:42:03.596 8[2468:507] date is 2018-11-22 16:00:31 +0000

[[54]]:

2014-07-20 17:42:03.597 8[2468:507] china_calar style is 3929-11-22 16:00:31 +0000

[[59]]:

2014-07-20 17:42:03.599 8[2468:507] 时区缩写:GMT+8

[[61]]:

2014-07-20 17:42:03.601 8[2468:507] time data is <545a6966 00000000 00000000 00000000 00000000 00000003 00000003 00000000 00000011 00000003 0000000c b0fe9a9b c85c0180 c8fa2770 c9d50e80 cadb5af0 1eba3600 1f697f70 207e6880 21496170 225e4a80 23294370 24476700
25125ff0 26274900 26f241f0 28072b00 28d223f0 02010201 02010201 02010201 02010201 02000071 e5000000 007e9001 04000070 8000084c 4d540043 44540043 53540000 00000000 00>

[[69]]:

2014-07-20 17:42:03.602 8[2468:507] time with zone : 2014-07-20 09:42:03 +0000

[[74]]:

2014-07-20 17:42:03.603 8[2468:507] init time_zone is Asia/Harbin (GMT+8) offset 28800

[[76]]:

2014-07-20 17:42:03.604 8[2468:507] date is 2019-10-10 19:14:59 +0000

[[79]]:

2014-07-20 17:42:03.604 8[2468:507] date is 2019-10-11 03:14:59 +0000

[[82]]:

2014-07-20 17:42:03.605 8[2468:507] fix_str is 2019-10-11 11:14:59

[[85]]:

2014-07-20 17:42:03.606 8[2468:507] date is 2019-10-11 11:14:59 +0000

要注意的是,我开始在用NSDateFormatter转换时间时,会发现设置时区后,转换的时间时区总是不对,后来发现NSDateFormatter总会把任意时区时间转换为GMT时间,如果你是GMT+8时区,即中国标准时间,则会将时间减去8小时。就像代码中最后一个例子,如果你不设置zone的时区,默认会使用本机时区,我这里就是GMT+8时区,则date对象实际上时间为2019-10-11 03:14:59减去8小时哦。当我们把f对象的时区变为GMT后,则时间上就不会有任何差别。所以你想显示当前时间是不可以的:

NSDate *now2 = [NSDate date];
msg(@"now2 is %@",now2);

当前时间是 2014-07-20 17:49:10,可是你显示出来会减去8小时的哦,你必须如下做转换:

NSDate *now2 = [NSDate date];
		msg(@"now2 is %@",now2);
		NSDateFormatter *f2 = [[NSDateFormatter alloc] init];
		[f2 setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
		[f2 setTimeZone:[NSTimeZone timeZoneWithName:@"GMT+8"]];
		NSString *now2_str = [f2 stringFromDate:now2];
		msg(@"now2 is %@",now2_str);

了解了吧?运行结果如下:

2014-07-20 17:52:59.513 8[2502:507] now2 is 2014-07-20 09:52:59 +0000

[[93]]:

2014-07-20 17:52:59.513 8[2502:507] now2 is 2014-07-20 17:52:59


上一篇:[Android]Button按下后修改背景图


下一篇:机器学习之sklearn——SVM