隔了好久才有了这新的一篇,还是无奈的时间啊!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. <<精通iOS开发>>第14章例子代码彻底清除警告

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上一篇我们解决了<<精通iOS开发>> ...

  2. Android的ToggleButton和Switch以及AnalogColok和DigitalColok的用法-android学习之旅(二十)

    ToggleButton 和Switch简介 ToggleButton 和Switch都是继承了Button,所以他们的属性设置和Button差不多. 分别支持的属性 ToggleButton 的属性 ...

  3. 剑指Offer--排序算法小结

    剑指Offer--排序算法小结 前言 毕业季转眼即到,工作成为毕业季的头等大事,必须得认认真真进行知识储备,迎战笔试.电面.面试. 许久未接触排序算法了.平时偶尔接触到时自己会不假思索的百度,然后就是 ...

  4. 【一天一道LeetCode】#292. Nim Game

    一天一道LeetCode 从今天开始,调整规律,不按顺序做,从easy开始! 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 ...

  5. Android初级教程理论知识(第一章快速入门)

    一.综合介绍. Android项目的目录结构 Activity:应用被打开时显示的界面 src:项目代码 R.java:项目中所有资源文件的资源id Android.jar:Android的jar包, ...

  6. vbox centos安装增强工具

    就是虚拟机识别不了宿主机的usb接口,这个虚拟机有没有图形界面,看看怎么装. 一个是依赖包问题,另一个就是挂了安装包,但是我怎么找到它并安装上去的问题. 虚拟机是centos6.6哈 vbox4.3. ...

  7. ADFS3.0 Customizing the AD FS Sign-in Pages

    Windows Server2012R2自带的adfs是3.0的版本,不同于以前的版本的是3.0中登陆页面的定制化全部是通过powershell指令实现,官方的介绍链接如下:http://techne ...

  8. Android 6.0 运行时权限处理问题

    序 自从升级到Android M以来,最大的改变就是增加了运行时权限RuntimePermission,6.0以上的系统如果没有做适配,运行了targetSDK=23的App时就会报权限错误.我们知道 ...

  9. 谈谈Ext JS组件之引子

    Ext JS组件,对于Ext JS开发人员来说,应当不会陌生,毕竟做开发,都必须与它打交道.对于这样一个大家都熟悉的东西,为什么要用一个专题的形式来写呢?是否有这方面的需要?还不如去写点使用技巧? 确 ...

  10. oracle ebs应用产品安全性-数据访问权限集

    定义 数据访问权限集是一个重要的.必须设定的系统配置文件选项.对具有相同科目表.日历和期间类型的分类帐及其所有平衡段值或管理段值的定义读写权限,系统管理员将其分配至不同的责任以控制不同的责任对分类帐数 ...