NSDate/NSCalendar

参考文档

NSDate

1 . 时间全都用NSData处理
2 . 显示时直接转NSString即可显示正确东八区时间
3 . 通过DatePicker获取的时间是东八区,所以要先换成0时区,再转时间戳。

#pragma mark - NSDate
   //打印date1显示的是当前时间对应的0时区时间
    NSDate *date1 = [NSDate date];

    //前推两天时间(0时区)
    NSDate *date2 = [[NSDate alloc]initWithTimeInterval:- (60 * 60 * 24 * 2) sinceDate:date1];
    //当前时间往后推24小时(0时区)
    NSDate *date3 = [date1 dateByAddingTimeInterval:60 * 60 *24 ];   

    //String(东8区) ---> Date(0时区)2016-08-22 17:28:03 +0000
    NSString *str = @"2016年08月23日 1时28分03秒";
    NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc]init];
    dateFormatter1.dateFormat = @"YYYY年MM月dd日 HH时mm分ss秒";
    NSDate *date = [dateFormatter1 dateFromString:str];

   //将转换过来的时间是0时区的要手动加8小时,即可变成东八区的NSDate时间
    NSDate *strDate = [date dateByAddingTimeInterval:8 * 60 * 60];
    NSLog(@"=====%@",strDate);

    
    //Date(0时区)---> String(东八区)
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    dateFormatter.dateFormat = @"yyyy年MM月dd日 HH时mm分ss秒 Z";//时区
    NSString *dateStr = [dateFormatter stringFromDate:date];
    NSLog(@"%@",dateStr); 

   //字符串会自动变成正确时间:2016年08月23日 01时28分03秒 +0800
   //*******因为NSDate是0时区,NSString是东八区********//
 
时间差异
//显示零时区时间,差8个小时
 NSDate *date = [NSDate date];
 NSLog(@"当前时间%@",date);//2016-08-24 14:16:47 +0000

//字符串打印自动正确时间
 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
 NSString *dateStr = [dateFormatter stringFromDate:date];
 NSLog(@"%@",dateStr);  //2016-08-24 22:16:47
北京时间
   /****以NSDate显示当前时区时间就会有8小时差异****/

  //1.获取当前时间 零时区的时间
    NSDate *date = [NSDate date];
    NSLog(@"当前零时区时间 %@", date);//得到的是0时区的时间

    //2.获得本地时间 东八区 晚八个小时 以秒计时,
    NSDate *date1 = [NSDate dateWithTimeIntervalSinceNow:8 * 60 * 60];
    NSLog(@"今天此时的时间 %@",date1);

    //3.昨天此时的时间
    NSDate *yesterdayDate = [NSDate dateWithTimeIntervalSinceNow:(-24 + 8) * 60 * 60];
    NSLog(@"昨天此时的时间 %@",yesterdayDate);

    //4.明天此刻
    NSDate *tomorrowDate = [NSDate dateWithTimeInterval:24 * 60 * 60 sinceDate:date1];
    NSLog(@"明天此刻的时间 %@",tomorrowDate);
获取时间戳
//时间戳一定要对应的是0时区的
//时间戳应该是10位的,13位代表计算了毫秒,截取前十位就可以
// 时间戳,即1970.1.1 00:00:00为标准,某个时间与它的秒数,且NSDate必须是0时区的
NSDate *date = [NSDate date];
NSTimeInterval timeIn = [date timeIntervalSince1970];
NSLog(@"1970年1月1日0时0分0秒至今相差 %.0f 秒", timeIn);
NSDateFormatter
G              公元AD
YYYY           完整年
YY             年后两位
MM             月显示 1-12
MMM            英文月份简写
dd             日2位数
d              日1-2位数
EEE            简写星期几,如Sun
EEEE           星期几全写
aa             AM/PM
HH             24小时制
hh             12小时制
mm             分
ss             秒
S              毫秒

NSDatePicker

UIDatePicker 继承自UIContro,只是对UIPickerView的封装

 //高度216是固定的
    UIDatePicker *picker = [[UIDatePicker alloc]initWithFrame:CGRectMake(0, 0, 300, 216)];
    [self.view addSubview:picker];
    //选取模式
    picker.datePickerMode =UIDatePickerModeDateAndTime; //默认
    //UIDatePickerModeCountDownTimer  //倒计时hour,minute
    //UIDatePickerModeTime;           //AM/PM,Hour,minute
    //UIDatePickerModeDate;           //year,month,day
    //时间间隔
    picker.minuteInterval = 1;
    //日期范围
    //转到其它日期后会自动选择最近的日期
    NSDate* minDate = [[NSDate alloc]initWithTimeIntervalSinceNow:-60 * 60 * 24 * 3 ];
    NSDate* maxDate = [[NSDate alloc]initWithTimeIntervalSinceNow:60 * 60 * 24 * 3];
    picker.minimumDate = minDate;
    picker.maximumDate = maxDate;
    //获取日期
    //第1种方式
    NSDate *pickDate = picker.date;
    //第2种方式
    [picker addTarget:self action:@selector(goAction:) forControlEvents:UIControlEventValueChanged];

NSCalendar

Calendar新增的很多方法确实简单省事,但好些方法都是iOS 8.0后的方法

基础使用

  • (id)currentCalendar / + (id)autoupdatingCurrentCalendar

这两个类方法都将返回当前客户端的逻辑日历,
区别在于:currentCalendar取得的值会一直保持在cache中,第一次用此方法实例化对象后,即使修改了系统日历设定,这个对象也不会改变。而使用autoupdatingCurrentCalendar,当每次修改系统日历设定,其实例化的对象也会随之改变。

  • (id)initWithCalendarIdentifier:(NSString *)string
    根据提供的日历标示符初始化
    NSGregorianCalendar -- 公历
    NSBuddhistCalendar -- 佛教日历
    NSChineseCalendar -- 中国农历
    NSHebrewCalendar -- 希伯来日历
    NSIslamicCalendar -- 伊斯兰历
    NSIslamicCivilCalendar -- 伊斯兰教日历
    NSJapaneseCalendar -- 日本日历
    NSRepublicOfChinaCalendar -- 中华民国日历(台湾)
    NSPersianCalendar -- 波斯历
    NSIndianCalendar -- 印度日历
    NSISO8601Calendar -- ISO8601

  • (void)setFirstWeekday:(NSUInteger)weekday
    设置每周的第一天从星期几开始,比如:1代表星期日开始,2代表星期一开始,以此类推。默认值是1

  • (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date
    获取一个小的单位在一个大的单位里面的序数
    NSCalendarUnit包含:
    NSEraCalendarUnit -- 纪元单位。
    对于NSGregorianCalendar(公历)来说,有公元前(BC)和公元(AD);
    对于其它历法可能有很多,例如日本和历是以每一代君王统治来做计算。
    NSYearCalendarUnit -- 年单位。
    NSMonthCalendarUnit -- 月单位。范围为1-12
    NSDayCalendarUnit -- 天单位。范围为1-31
    NSHourCalendarUnit -- 小时单位。范围为0-24
    NSMinuteCalendarUnit -- 分钟单位。范围为0-60
    NSSecondCalendarUnit -- 秒单位。范围为0-60
    NSWeekCalendarUnit -- 周单位。范围为1-53
    NSWeekdayCalendarUnit -- 星期单位。范围为1-7
    NSQuarterCalendarUnit -- 几刻钟,就是15分钟。范围为1-4

    NSWeekOfMonthCalendarUnit -- 月包含的周数。最多为6个周
    NSWeekOfYearCalendarUnit -- 年包含的周数。最多为53个周

   NSCalendar *calendar = [NSCalendar currentCalendar];
    //以2001-1-1 0:0:0的偏移秒数来初始化
    NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:10];
    //[calendar setFirstWeekday:2];
    NSInteger count = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
    NSLog(@"%ld",count);

默认情况下第一个周有5天,如果将minimumDaysInFirstWeek设置为6天,则原本是第一周的1月1日--1月5日被划分到了上一年,返回0;
而1月6日--1月12日升为第一周,1月13日--1月19日升为第二周。。依此类推。
所以需要关注的是minimumDaysInFirstWeek与实际第一周包含天数的大小比较,如果提供的minimumDaysInFirstWeek比实际第一周的天数小,则一切不变;否则统计"一年中第几周"、"一个月中第几周"会产生变化。

    NSDateComponents *compt = [[NSDateComponents alloc] init];
    [compt setYear:2013];
    [compt setMonth:1];
    [compt setDay:20];
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDate *date = [calendar dateFromComponents:compt];
    
    //[calendar setMinimumDaysInFirstWeek:6];
    NSInteger count = [calendar ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitYear forDate:date];
    NSLog(@"%ld",count);

A .取得一个NSDate对象的1个或多个部分
-(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)date

#pragma mark - NSCalendar
    //初始化创建日历
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSCalendarUnit unit =  NSCalendarUnitDay |
                         NSCalendarUnitMonth |
                          NSCalendarUnitYear |
                        NSCalendarUnitWeekday;
    
    //获取时间相应日期
    NSDateComponents *components1 = [calendar components:unit fromDate:date1];
    NSDateComponents *components2 = [calendar components:unit fromDate:date2];

    //周日weekday=1,周六weekday=7
    NSLog(@"weekday--%ld,weekday--%ld",components1.weekday,components2.weekday);
    NSLog(@"day---%ld,day---%ld,%ld,",components1.day,components2.day, components1.day - components2.day);
    
    //返回两个时间的差值组件,option暂时没意义设为0
    NSDateComponents *components3 = [calendar components:unit
                                                fromDate:date2
                                                  toDate:date1
                                                 options:0];
    NSDateComponents *components4 = [calendar components:unit
                                      fromDateComponents:components2
                                        toDateComponents:components1
                                                 options:0];
    NSLog(@"%ld,%ld",components3.day ,components4.day);
    
    //是否当天日期
    NSLog(@"是否是今天--%d",[calendar isDateInToday:date1]);
    //是否是明天
    NSLog(@"是否是明天--%d",[calendar isDateInTomorrow:date3]);
    //是否是昨天
    NSLog(@"是否是昨天%d",[calendar isDateInYesterday:date2]);
    //是否是周六/周末
    NSLog(@"是否是同日%d",[calendar isDateInWeekend:date2]);
    //是否同一天
    NSLog(@"是否是同一天--%d",[calendar isDate:date1 inSameDayAsDate:date2]);
    //是否在指定的同一单位内
    NSLog(@"是否是同一月--%d",[calendar isDate:date1 equalToDate:date2 toUnitGranularity:NSCalendarUnitMonth]);


    //苹果官方不推荐使用week
    NSLog(@"week(该年第几周):%i", dateComponents.week);
    NSLog(@"weekOfYear(该年第几周):%i", dateComponents.weekOfYear);
    NSLog(@"weekOfMonth(该月第几周):%i", dateComponents.weekOfMonth);

注意:

  • 需要注意的是,只有明确指定了unitFlags,NSDateComponents相应的那一部分才有值。

B . 取得两个NSDate对象的时间间隔
-(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options : (NSUInteger)opts

// 先定义一个遵循某个历法的日历对象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

//根据两个时间点,定义NSDateComponents对象,从而获取这两个时间点的时差
NSDateComponents *componets = [calendar components:NSCalendarUnitDay fromDate:[NSDate date] toDate:[NSDate dateWithTimeIntervalSinceNow:24 * 60 * 60 * 8] options:0];
NSLog(@"%ld",componets.day);

注意:

  1. 得到的NSDateComponents对象可能会包含负数。
    例如:
    当toDate比fromDate晚10秒,second部分返回10;
    当toDate比fromDate早10秒,second部分返回-10

  2. 当指定unitFlags返回多个部分时,相隔的时间由多个部分共同组成(而不是独立去表示)。例如:上面的例子时间相差5小时1分15秒,如果指定只返回second部分,将得到18075秒;如果指定返回minute和second部分,将得到301分15秒;如果指定返回hour、minute和second,将得到5小时1分15秒

C .根据据NSDateComponents对象得到一个NSDate对象
-(NSDate *)dateFromComponents:(NSDateComponents *)comps

//先定义一个遵循某个历法的日历对象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

// 定义一个NSDateComponents对象,设置一个时间点
NSDateComponents *dateComponentsForDate = [[NSDateComponents alloc] init];
[dateComponentsForDate setDay:6];
[dateComponentsForDate setMonth:5];
[dateComponentsForDate setYear:2004];

//根据设置的dateComponentsForDate获取历法中与之对应的时间点
//这里的时分秒会使用NSDateComponents中规定的默认数值,一般为0或1。
NSDate *date = [greCalendar dateFromComponents: dateComponentsForDate];

//得到本地时间,避免时区问题
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger interval = [zone secondsFromGMTForDate:date];
NSDate *localeDate = [date dateByAddingTimeInterval:interval];

NSLog(@"%@",date);

D. 在参数date基础上,增加一个NSDateComponents类型的时间增量
-(NSDate *)dateByAddingComponents:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts

// 定义一个NSDateComponents对象,设置一个时间段
NSDateComponents *dateComponentsAsTimeQantum = [[NSDateComponents alloc] init];
[dateComponentsAsTimeQantum setDay:6];

//在当前历法下,获取6天后的时间
NSDate *date = [greCalendar dateByAddingComponents:dateComponentsAsTimeQantum toDate:[NSDate date] options:0];

//得到本地时间,避免时区问题
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSInteger interval = [zone secondsFromGMTForDate:date];
NSDate *localeDate = [date dateByAddingTimeInterval:interval];

NSLog(@"%@",date);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容