隔了好久才有了这新的一篇,还是无奈的时间啊!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. 剑指Offer——京东校招笔试题+知识点总结

    剑指Offer--京东校招笔试题+知识点总结 笔试感言 经过一系列的笔试,发觉自己的基础知识还是比较薄弱的,尤其是数据结构和网络,还有操作系统.工作量还是很大的.做到精确制导的好方法就是在网上刷题,包 ...

  2. Android View框架总结(一)

    View和Activity的区别 View有哪些? ViewGroup是什么? 为什么Google产生ViewGroup? View的层级结构是什么? View的onMeasure()/onLayou ...

  3. [IDE工具配置]myeclipse 2014 专业版 安装 svn插件

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/38342411 本文作者:sushengmiyan 团队合作的项目肯定少不了版本控制,那 ...

  4. 浅谈C++中的友元关系

    在封装中C++类数据成员大多情况是private属性:但是如果接口采用多参数实现肯定影响程序效率:然而这时候如果外界需要频繁访问这些私有成员,就不得不需要一个既安全又理想的"后门" ...

  5. JSP自定义标签必知必会

    自定义标签技术自sun公司发布以来,便一向很受欢迎!下面我就来谈一谈如何实现自定义标签,以及如何使用自定义标签. 如何实现自定义标签 首先我们应该知道原理,不管是标签还是JSP,本身实际上都会被JSP ...

  6. Oracle EBS SLA 详解

    SLA概述 SLA :子分类账(Subledger Accounting),这个在R12中大力宣扬的内容,我们通常的认为总账就是对Journal的汇总,但是在实际的操作中我们会发现,对于Sub sys ...

  7. Android进阶(十)Android 发邮件

    最近在做的APP涉及到发邮件,总结如下: 在android里进行邮件客户端开发可以有两种方式: 在邮件客户端的设计中,可以采用两种方法. 一种是调用android系统自带的邮件服务 优点:这种方法比较 ...

  8. UNIX环境高级编程——文件和目录

    一.获取文件/目录的属性信息 int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf); in ...

  9. avcodec_decode_video2()解码视频后丢帧的问题解决

    使用libav转码视频时发现一个问题:使用下面这段代码解码视频时,视频尾巴上会丢掉几帧. while(av_read_frame(ifmt_ctx,&packet) >= 0){ ret ...

  10. rt-thread的位图调度算法分析

    转自:http://blog.csdn.net/prife/article/details/7077120 序言 期待读者 本文期待读者有C语言编程基础,后文中要分析代码,对其中的一些C语言中的简单语 ...