隔了好久才有了这新的一篇,还是无奈的时间啊!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


obj-c编程10:Foundation库中类的使用(5)[时间对象]的更多相关文章

  1. obj-c编程10:Foundation库中类的使用(2)[字符串,数组]

    Foundation库的内容不可谓不多,就算很精简的说篇幅也受不了啊!笨猫一向反对博客文章一下子拖拖拉拉写一大坨!KISS哦!so将上一篇文章再分一篇来说,于是有了这篇,可能还会有(3)哦... 我发 ...

  2. obj-c编程10:Foundation库中类的使用(6)[线程和操作队列]

    任何语言都不能避而不谈线程这个东东,虽然他是和平台相关的鸟,虽说unix哲学比较讨厌线程的说...线程不是万能灵药,但有些场合还是需要的.谈到线程就不得不考虑同步和死锁问题,见如下代码: #impor ...

  3. obj-c编程10:Foundation库中类的使用(4)[文件管理,查询当前进程信息]

    接上一篇文件管理博文.我们可以用NSPathUtilities.h中包含的NSString函数和分类扩展来以兼容的方式处理路径.下面凡是有系统编程经验的童鞋都知道是啥意思了: #import < ...

  4. obj-c编程10:Foundation库中类的使用(3)[文件管理]

    好吧,不管神马系统都无可避免的要说到文件,目录,路径(PATH)管理的内容,下面我们来看看在F库中对他们的支持.我简单看了下,不谈其他光从方法命名来说就多少显得有点复杂,如果和ruby相比就呵呵了. ...

  5. obj-c编程10:Foundation库中类的使用(1)[数字,字符串]

    我们知道在mac或iphone上编程最终逃不开os x平台,你无法在windows或linux上开发纯正的apple程序.(so不要舍不得银子买mac啦)虽说linux和windows上有移植的obj ...

  6. C++的XML编程经验――LIBXML2库使用指南[转]

    C++的XML编程经验――LIBXML2库使用指南 写这篇文章的原因有如下几点:1)C++标准库中没有操作XML的方法,用C++操作XML文件必须熟悉一种函数库,LIBXML2是其中一种很优秀的XML ...

  7. Java 库:为 Java 程序员而生的 10 + 最佳库

    众所周知,Java 的生态环境相当庞大,包含了数量相当可观的官方及第三方库.利用这些库,可以解决在用 Java 开发时遇到的各类问题,让开发效率得到显著提升. 举些例子,最常用的官方库有 java.l ...

  8. C++的XML编程经验――LIBXML2库使用指南

    C++的XML编程经验――LIBXML2库使用指南 写这篇文章的原因有如下几点:1)C++标准库中没有操作XML的方法,用C++操作XML文件必须熟悉一种函数库,LIBXML2是其中一种很优秀的XML ...

  9. 进阶Java编程(10)反射与简单Java类

    1,传统属性自动赋值弊端 简单Java类主要由属性构成,并且提供有setter与getter类,同时简单Java类最大的特征就是通过对象保存相应的类属性的内容.但是如果使用传统的简单Java类开发,那 ...

随机推荐

  1. 初探linux子系统集之timer子系统(二)

    想着博客中还没有翻译过一篇文章,虽然英文水平有限,但是借助google翻译慢慢地翻译出一篇文章也是不错的选择.那就来学习下hrtimer的文档吧,翻译的略搓,可以直接跳过这篇,这里仅作为学习的过程!^ ...

  2. 后端分布式系列:分布式存储-HDFS Client 设计实现解析

    前面对 HDFS NameNode 和 DataNode 的架构设计实现要点做了介绍,本文对 HDFS 最后一个主要构成组件 Client 做进一步解析. 流式读取 HDFS Client 为客户端应 ...

  3. CentOS配置

    1.在Vmware中安装好虚拟机. 2.客户机(即虚拟机中的centos)网络连接使用仅主机模式Host-only 3.在主机中网络配置上,配置IP地址 1.使用PieTTY远程连接该虚拟机 2.使用 ...

  4. 软考之路--从生活着手,看PV如何操作

    PV操作,是软考当中一个很重要的考点,一听到这个名词,顿时赶脚高大上有么有,在软考的历年试题中,也不乏PV操作的身影,老师也对PV操作进行了一次讲课,那时年少,听得稀里糊涂,也不是很理解,在小编的理解 ...

  5. 海量数据挖掘MMDS week5: 计算广告Computational Advertising

    http://blog.csdn.net/pipisorry/article/details/49428053 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...

  6. Django练习——博客系统小试

    在上一篇博客Todolist的基础上(http://blog.csdn.net/hcx25909/article/details/24251427),本周继续进行实践,这次我要搭建一个简单的博客系统. ...

  7. java线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用

    简单说下Executors类,提供的一系列创建线程池的方法: 他们都有两个构造方法 1. --------newFixedThreadPool (创建一个定长线程池,可控制线程最大并发数,超出的线程会 ...

  8. 9.2、Libgdx的输入处理之鼠标、触摸和键盘

    (官网:www.libgdx.cn) Libgdx支持的最主要的设备是desktop或浏览器的鼠标支持,Android的触摸屏支持和键盘的支持.我们接下来了解一下. 键盘 用户按下或释放一个按键生成了 ...

  9. leetcode 104 Maximum Depth of Binary Tree二叉树求深度

    Maximum Depth of Binary Tree Total Accepted: 63668 Total Submissions: 141121 My Submissions Question ...

  10. [Django] 单元测试小记

    从前很少写单元测试了,特别是web应用.最近不知不觉喜欢起来这个事情了,发现单元测试对于软件的模块,正交性有很大促进作用,因为函数,模块写的不合理,单元测试写起来就麻烦的多呀.公司的项目一直都是用Dj ...