ios--NSCalendar NSDateComponents

原文:

ios时间那点事--NSCalendar NSDateComponents

http://my.oschina.net/yongbin45/blog/156181

目录[-]

iOS时间那点事

NSCalendar + NSDateComponents

  1. 历法能使人类确定每一日再无限的时间中的确切位置并记录历史。
  2. 日历,历法,一般历法都是遵循固定的规则的,具有周期性。日历都是已知的或可预测的。
  3. 任何一种具体的历法,首先必须明确规定起始点,即开始计算的年代,这叫“纪元”;以及规定一年的开端,这叫“岁首”。此外,还要规定每年所含的日数,如何划分月份,每月有多少天等等。
  4. NSCalendar对世界上现存的常用的历法进行了封装,既提供了不同历法的时间信息,又支持日历的计算。
  5. NSDateFomatter表示的时间默认以公历(即阳历)为参考,可以通过设置calendar属性变量获得特定历法下的时间表示。
  6. NSDate是独立与任何历法的,它只是时间相对于某个时间点的时间差;NSDate是进行日历计算的基础。
  7. NSDateComponents将时间表示成适合人类阅读和使用的方式,通过NSDateComponents可以快速而简单地获取某个时间点对应的“年”,“月”,“日”,“时”,“分”,“秒”,“周”等信息。当然一旦涉及了年月日时分秒就要和某个历法绑定,因此NSDateComponents必须和NSCalendar一起使用,默认为公历。
  8. NSDateComponents除了像上面说的表示一个时间点外,还可以表示时间段,例如:两周,三个月,20年,7天,10分钟,50秒等等。时间段用于日历的计算,例如:获取当前历法下,三个月前的某个时间点。
  9. 可以说,要获取某个时间点在某个历法下的表示,需要NSDateComponents;要计算当前时间点在某个历法下对应的一个时间段前或后的时间点,需要NSDateComponents。
  10. NSDateComponents返回的day, week, weekday, month, year这一类数据都是从1开始的。因为日历是给人看的,不是给计算机看的,从0开始就是个错误。

NSDateComponents实例化的方式

第一种:
    <!-- lang: cpp -->
//  先定义一个遵循某个历法的日历对象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
//  通过已定义的日历对象,获取某个时间点的NSDateComponents表示,并设置需要表示哪些信息(NSYearCalendarUnit, NSMonthCalendarUnit, NSDayCalendarUnit等)
NSDateComponents *dateComponents = [greCalendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit | NSWeekOfMonthCalendarUnit | NSWeekOfYearCalendarUnit fromDate:[NSDate date]];
NSLog(@"year(年份): %i", dateComponents.year);
NSLog(@"quarter(季度):%i", dateComponents.quarter);
NSLog(@"month(月份):%i", dateComponents.month);
NSLog(@"day(日期):%i", dateComponents.day);
NSLog(@"hour(小时):%i", dateComponents.hour);
NSLog(@"minute(分钟):%i", dateComponents.minute);
NSLog(@"second(秒):%i", dateComponents.second);

//  Sunday:1, Monday:2, Tuesday:3, Wednesday:4, Friday:5, Saturday:6
NSLog(@"weekday(星期):%i", dateComponents.weekday);

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

若获取dateComponents对象时,设置components的时候未添加NSYearCalendarUnit,dateComponents.year将返回错误的数值,其他的也一样,所以使用NSDateComponents表示时间时,要确保需要使用的数据都在componets中添加了。

第二种:
    <!-- lang: cpp -->
//  先定义一个遵循某个历法的日历对象
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 *dateFromDateComponentsForDate = [greCalendar dateFromComponents:dc];

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

//  在当前历法下,获取6天后的时间点
NSDate *dateFromDateComponentsAsTimeQantum = [greCalendar dateByAddingComponents:dateComponentsAsTimeQantum toDate:[NSDate date] options:0];
第三种:
    <!-- lang: cpp -->
//  先定义一个遵循某个历法的日历对象
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

//  根据两个时间点,定义NSDateComponents对象,从而获取这两个时间点的时差
NSDateComponents *dateComponents = [greCalendar components:NSYearCalendarUnit fromDate:[NSDate dateWithTimeIntervalSince1970:0] toDate:[NSDate date] options:0];
NSLog(@"number of years:%i", dateComponents.year);

NSCalendar中比较重要的方法和概念

firstWeekday

firstWeekday是大家比较容易浑淆的东西。

大家在使用dateComponents.weekday获取某天对应的星期时,会发现,星期日对应的值为1,星期一对应的值为2,星期二对应的值为3,依次递推,星期六对应的值为7,这与我们平时理解的方式不一样。然后,我们就开始找是不是可以设置这种对应关系。终于,我们在NSCalendar中发现了firstWeekday这个变量,从字面意思上看貌似就是我们寻找的那个东西。可是,设置过firstWeekday后,我们又发现完全没有作用,真是郁闷啊!其实,大家不必郁闷,因为郁闷也没用,iOS中规定的就是周日为1,周一为2,周二为3,周三为4,周四为5,周五为6,周六为7,无法通过某个设置改变这个事实的,只能在使用的时候注意一下这个规则了。那firstWeekday是干什么用的呢?大家设置一下firstWeekday,再获取一下dateComponents.weekOfYear或dateComponents.weekOfMonth,看看返回的数据是否发生了变化。firstWeekday的作用确实是修改当前历法中周的起始位置,但是不能修改周日对应的数值,只能修改一年或一个月中周的数量,以及周的次序。

-(NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;
答疑解惑:
  1. Unit:单元
  2. NSRange:

    typedef struct _NSRange {

        NSUInteger location;
    NSUInteger length;
    

    } NSRange;

我们大致可以理解为:某个时间点所在的“小单元”,在“大单元”中的数量(返回值range的location属性变量的值一般是错误的)。例如:

            <!-- lang: cpp -->
    //  当前时间对应的月份中有几天
    [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;
    //  当前时间对应的月份中有几周(前面说到的firstWeekday会影响到这个结果)
    [[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;
-(NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;

我们大致可以理解为:某个时间点所在的“小单元”,在“大单元”中的位置(从1开始)。例如:

           <!-- lang: cpp -->
    //  当前时间对应的周是当前年中的第几周
    [[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekOfYearCalendarUnit inUnit:NSYearCalendarUnit forDate:self];
    [[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];

    //  当前时间对应的周是当前月中的第几周
    [[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekOfMonthCalendarUnit inUnit:NSYearCalendarUnit forDate:self];
    [[NSCalendar currentCalendar] ordinalityOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]];

在这里:NSWeekOfYearCalendarUnit, NSWeekOfMonthCalendarUnit与NSWeekCalendarUnit的使用结果相同,为了避免浑淆,建议在此处使用NSWeekCalendar,而定义NSDateComponents时使用NSWeekOfYearCalendarUnit和NSWeekOfMonthCalendarUnit。

-(BOOL)rangeOfUnit:(NSCalendarUnit)unit startDate:(NSDate *)datep interval:(NSTimeInterval )tip forDate:(NSDate *)date;

我们大致可以理解为:“某个时间点”所在的“单元”的起始时间,以及起始时间距离“某个时间点”的时差(单位秒)。例如:

    <!-- lang: cpp -->
    NSDate *startDateOfYear;
    NSDate *startDateOfMonth;
    NSDate *startDateOfWeek;
    NSDate *startDateOfDay;
    NSTimeInterval TIOfYear;
    NSTimeInterval TIOfMonth;
    NSTimeInterval TIOfWeek;
    NSTimeInterval TIOfDay;
    [[NSCalendar currentCalendar] rangeOfUnit:NSYearCalendarUnit startDate:&startDateOfYear interval:&TIOfYear forDate:[NSDate date]];
    [[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startDateOfMonth interval:&TIOfMonth forDate:[NSDate date]];
    [[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit startDate:&startDateOfWeek interval:&TIOfWeek forDate:[NSDate date]];
    [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startDateOfDay interval:&TIOfDay forDate:[NSDate date]];
    NSLog(@"firstDateOfYear:%@, FirstDateOfMonth:%@, FirstDateOfWeek:%@, FirstDateOfDay:%@", startDateOfYear, startDateOfMonth, startDateOfWeek, startDateOfDay);
    NSLog(@"TIOfYear:%f, TIOfMonth:%f, TIOfWeek:%f, TIOfDay:%f", TIOfYear, TIOfMonth, TIOfWeek, TIOfDay);

关于NSCalendar和NSDateComponents的介绍暂时说到这里。

时间: 2024-10-12 05:19:06

ios--NSCalendar NSDateComponents的相关文章

NSCalendar NSDateComponents

目录[-] iOS时间那点事 NSCalendar + NSDateComponents NSDateComponents实例化的方式 第一种: 第二种: 第三种: NSCalendar中比较重要的方法和概念 firstWeekday -(NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date; 答疑解惑: -(NSUInteger)ordinalityOfU

IOS,利用NSDateComponents,NSCalendar判断当前的时间点是否在某个时间段内的方法

1 - (BOOL)isBetweenFromHour:(NSInteger)fromHour toHour:(NSInteger)toHour 2 { 3 NSDate *date8 = [self getCustomDateWithHour:8]; 4 NSDate *date23 = [self getCustomDateWithHour:23]; 5 NSDate *currentDate = [NSDate date]; 6 7 if ([currentDate compare:dat

用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.android实现自绘日期选择控件 目的: 通过一个相对复杂的自定义自绘控件来分享: 1.ios以及android自定义自绘控件的开发流程 2.objc与c/c++混合编程 3.android ndk的环境配置,android studio ndk的编译模式,swig在android ndk开发中的作

ios日期格式转换

转自:http://blog.csdn.net/l_ch_g/article/details/8217725 1.如何如何将一个字符串如“ 20110826134106”装化为任意的日期时间格式,下面列举两种类型: NSString* string = @"20110826134106"; NSDateFormatter *inputFormatter = [[[NSDateFormatter alloc] init] autorelease]; [inputFormatter set

iOS CALayer视图图层

在iOS中都会牵扯到图形转换,动画效果,添加视图,等等的一系列问题,在设计页面,设计图形,添加动画的时候都会使用到这个知识. 简单的说他就是视图的图层,但又不是视图,因为视图可以和用户交互,添加响应事件,添加视图等等,但是CALayer并不可以添加响应事件等等,它只是一个视图的图层,就是这个图片的显示层,展示层,只能够显示内容,比如展示背景颜色,展示图片,设置边框,等等. UIView上面的rootLayer 发生改变的话 子图层也会发生变化 如果想要改变 button的视图形状边框等,要改变的

iOS动画之美丽的时钟

1.终于效果图 2.实现思路 在ios中默认是绕着中心点旋转的,由于锚点默认在图层的中点,要想绕着下边中心点转,须要改变图层锚点的位置. 依据锚点.设置position坐标.为时钟的中点. 思考秒针旋转的角度,怎么知道当前秒针旋转到哪,当前秒针旋转的角度 = 当前秒数 * 每秒转多少°. 1> 计算一秒转多少° 360 * 60 = 6 2> 获取当前秒数.通过日历对象,获取日期组成成分 NSCalendar -> NSDateComponents -> 获取当前秒数 每隔一秒,获

iOS动画,漂亮的时钟

1.最终效果图 2.实现思路 在ios中默认是绕着中心点旋转的,因为锚点默认在图层的中点,要想绕着下边中心点转,需要改变图层锚点的位置. 根据锚点,设置position坐标,为时钟的中点. 思考秒针旋转的角度,怎么知道当前秒针旋转到哪,当前秒针旋转的角度 = 当前秒数 * 每秒转多少°. 1> 计算一秒转多少° 360 * 60 = 6 2> 获取当前秒数,通过日历对象,获取日期组成成分 NSCalendar -> NSDateComponents -> 获取当前秒数 每隔一秒,获

iOS下日期的处理

NSDate存储的是世界标准时(UTC),输出时需要根据时区转换为本地时间 Dates         NSDate类提供了创建date,比较date以及计算两个date之间间隔的功能.Date对象是不可改变的.         如果你要创建date对象并表示当前日期,你可以alloc一个NSDate对象并调用init初始化: C代码  NSDate *now = [[NSDate alloc] init];                或者使用NSDate的date类方法来创建一个日期对象.

iOS 时间处理(转)

NSDate NSDate对象用来表示一个具体的时间点. NSDate是一个类簇,我们所使用的NSDate对象,都是NSDate的私有子类的实体. NSDate存储的是GMT时间,使用的时候会根据 当前应用 指定的 时区 进行时间上的增减,以供计算或显示. 可以快速地获取的时间点有: now (当前时间点) 相对于1 January 2001, GMT的时间点 相对于1970的时间点 distantFuture (不可达到的未来的某个时间点) distantPast (不可达到的过去的某个时间点