OC Foundation框架 日期与时间

Posted Billy Miracle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OC Foundation框架 日期与时间相关的知识,希望对你有一定的参考价值。

OC为处理日期、时间提供了NSDate、NSCalendar对象,还提供了日期格式器来处理日期与字符串之间的转换。

日期与时间(NSDate)

下面通过一个程序来介绍NSDate类的常见方法的用途

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //获取当前日期、时间的NSDate
        NSDate* date1 = [NSDate date];
        NSLog(@"%@", date1);
        //获取从当前时间开始,一天之后的日期
        NSDate* date2 = [[NSDate alloc] initWithTimeIntervalSinceNow: 3600*24];
        NSLog(@"%@", date2);
        //获取从当前时间开始,3天之前的日期
        NSDate* date3 = [[NSDate alloc] initWithTimeIntervalSinceNow: -3*3600*24];
        NSLog(@"%@", date3);
        //获取从1970年1月1日开始,20年后的日期
        NSDate* date4 = [[NSDate alloc] initWithTimeIntervalSince1970: 3600*24*366*20];
        NSLog(@"%@", date4);
        //获取系统当前的NSLocale
        NSLocale* cn = [NSLocale currentLocale];
        //获取NSDate在当前NSLocale下对应的字符串
        NSLog(@"%@", [date1 descriptionWithLocale: cn]);
        //获取两个日期之间较早的日期
        NSDate* earlier = [date1 earlierDate: date2];
        //获取两个日期之间较晚的日期
        NSDate* later = [date1 laterDate: date2];
        NSLog(@"%@ < %@", earlier, later);
        //比较两个日期,compare: 方法返回NSComparisonResult枚举值
        //该枚举类型包含NSOrderedAscending、NSOrderedSame和
        //NSOrderedDescending三个值
        //分别代表调用compare: 的日期位于被比较日期之前、相同、之后
        switch ([date1 compare: date3]) {
            case NSOrderedAscending:
                NSLog(@"dete1位于date3之前");
                break;
            case NSOrderedSame:
                NSLog(@"date1与date3日期相等");
                break;
            case NSOrderedDescending:
                NSLog(@"dete1位于date3之后");
                break;
        }
        //获取两个时间之间的时间差
        NSLog(@"date1与date3之间时间差%g秒",[date1 timeIntervalSinceDate: date3]);
        //获取指定时间与现在时间差
        NSLog(@"date2与现在时间差%g秒", [date2 timeIntervalSinceNow]);
    }
    return 0;
}

可以看出,创建NSDate的类方法与实例方法基本相似,只是类方法以date开头,而实例方法以init开头。
输出:

Wed Jun  2 15:15:59 2021
Thu Jun  3 15:15:59 2021
Sun May 30 15:15:59 2021
Tue Jan 16 08:00:00 1990
202162日 星期三 中国标准时间 下午3:15:59
Wed Jun  2 15:15:59 2021 < Thu Jun  3 15:15:59 2021
dete1位于date3之后
date1与date3之间时间差259200秒
date2与现在时间差86400

日期格式器(NSDateFormatter)

NSDateFormatter代表一个日期格式器,它的功能就是完成NSDate与NSString之间的转换。
转换步骤:

  1. 创建一个NSDateFormatter对象
  2. 调用NSDateFormatter的setDateStyle:、 setTimeStyle:方法设置格式化日期、时间的风格。其中,日期、时间风格支持如下几个枚举值。
  • NSDateFormatterNoStyle:不显示日期、时间的风格
  • NSDateFormatterShortStyle:显示短的日期、时间风格
  • NSDateFormatterMediumStyle:显示中等的日期、时间风格
  • NSDateFormatterLongStyle:显示长的日期、时间风格
  • NSDateFormatterFullStyle:显示完整的日期、时间风格

如果打算使用自己的格式模版,则调用NSDateFormatter的setDateFormat: 方法设置日期、时间的模版即可。

  1. 如果需要将NSDate转换为NSString,则调用NSDateFormatter的stringFromDate: 方法执行格式化即可;如果需要将NSString转换为NSDate,则调用NSDateFormatter的dateFromString: 方法执行格式化即可。

示例:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //需要被格式化的时间
        //获取现在的时间或者从1970年1月1日开始,20年后的日期
        //NSDate* dt = [NSDate dateWithTimeIntervalSince1970: 3600*24*366*20];
        NSDate* dt = [NSDate date];
        //创建两个NSLocale,分别代表中国、美国
        NSLocale* locales[] = {[[NSLocale alloc] initWithLocaleIdentifier: @"zh_CN"] , [[NSLocale alloc] initWithLocaleIdentifier: @"en_US"]};
        NSDateFormatter* df[8];
        //为上面两个NSLocale创建8个NSDateFormatter对象
        for (int i = 0; i < 2; ++i) {
            df[i * 4] = [[NSDateFormatter alloc] init];
            //设置NSDateFormatter的日期、时间风格
            [df[i * 4] setDateStyle: NSDateFormatterShortStyle];
            [df[i * 4] setTimeStyle: NSDateFormatterShortStyle];
            //设置NSDateFormatter的NSLocale
            [df[i * 4] setLocale: locales[i]];
            df[i * 4 + 1] = [[NSDateFormatter alloc] init];
            //设置NSDateFormatter的日期、时间风格
            [df[i * 4 + 1] setDateStyle: NSDateFormatterMediumStyle];
            [df[i * 4 + 1] setTimeStyle: NSDateFormatterMediumStyle];
            //设置NSDateFormatter的NSLocale
            [df[i * 4 + 1] setLocale: locales[i]];
            df[i * 4 + 2] = [[NSDateFormatter alloc] init];
            //设置NSDateFormatter的日期、时间风格
            [df[i * 4 + 2] setDateStyle: NSDateFormatterLongStyle];
            [df[i * 4 + 2] setTimeStyle: NSDateFormatterLongStyle];
            //设置NSDateFormatter的NSLocale
            [df[i * 4 + 2] setLocale: locales[i]];
            df[i * 4 + 3] = [[NSDateFormatter alloc] init];
            //设置NSDateFormatter的日期、时间风格
            [df[i * 4 + 3] setDateStyle: NSDateFormatterFullStyle];
            [df[i * 4 + 3] setTimeStyle: NSDateFormatterFullStyle];
            //设置NSDateFormatter的NSLocale
            [df[i * 4 + 3] setLocale: locales[i]];
        }
        for (int i = 0; i < 2; ++i) {
            switch (i) {
                case 0:
                    NSLog(@"------------中国日期格式------------");
                    break;
                case 1:
                    NSLog(@"------------美国日期格式------------");
                    break;
            }
            NSLog(@"SHORT格式的日期格式:%@", [df[i * 4] stringFromDate: dt]);
            NSLog(@"MEDIUM格式的日期格式:%@", [df[i * 4 + 1] stringFromDate: dt]);
            NSLog(@"LONG格式的日期格式:%@", [df[i * 4 + 2] stringFromDate: dt]);
            NSLog(@"FULL格式的日期格式:%@", [df[i * 4 + 3] stringFromDate: dt]);
        }
        NSDateFormatter* df2 = [[NSDateFormatter alloc] init];
        //设置自定义的格式模版
        [df2 setDateFormat:@"公元 yyyy 年 MM 月 DD 日 HH 时 mm 分"];
        //执行格式化
        NSLog(@"%@" , [df2 stringFromDate: dt]);
        NSString* dateStr = @"2021-06-01";
        NSDateFormatter* df3 = [[NSDateFormatter alloc] init];
        //根据日期字符串的格式设置格式模版
        [df3 setDateFormat: @"yyyy-MM-dd"];
        //将字符串转换为NSDate对象
        NSDate* date2 = [df3 dateFromString: dateStr];
        NSLog(@"%@" , date2);
    }
    return 0;
}

输出结果:
在这里插入图片描述

日历(NSCalendar)与日期组件(NSDateComponents)

为了能分开处理NSDate对象所包含的各个字段的数据,Foundation框架提供了NSCalendar对象,该对象包含如下两个常用方法。

  • (NSDateComponents*)components:fromDate: :从NSDate中提取年、月、日、时、分、秒各时间字段的信息。
  • dateFromComponents:(NSDateComponents*)comps :使用comps对象包含的年、月、日、时、分、秒各时间字段的信息来创建NSDate。

从NSDate对象中分开获取各时间字段的数值的步骤如下:

  1. 创建NSCalendar对象
  2. 调用NSCalendar的components: fromDate: 方法获取NSDate对象中各时间字段的数值,该方法返回一个NSDateComponents对象。
  3. 调用NSDateComponents对象的getter方法来获取各时间字段的数值。

使用各时间字段的数值来初始化NSDate对象的步骤如下:

  1. 创建NSCalendar对象
  2. 创建一个NSDateComponents对象,调用该对象的setter方法来设置各时间字段的数值
  3. 调用NSCalendar的dateFromComponents:(NSDateComponents*)方法初始化NSDate对象,该方法会返回一个NSDate对象。

示例:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //获取代表公历的NSCalendar对象
        NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSCalendarIdentifierGregorian];
        //获取当前日期
        NSDate* dt =[NSDate date];
        //定义一个时间字段的旗标,指定会获取指定年、月、日、时、分、秒、星期的信息
        unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday;
        //获取不同时间字段的信息
        NSDateComponents* comp = [gregorian components: unitFlags fromDate: dt];
        //获取各时间字段的数值
        NSLog(@"现在是%ld年", comp.year);
        NSLog(@"现在是%ld月", comp.month);
        NSLog(@"现在是%ld日", comp.day);
        NSLog(@"现在是%ld时", comp.hour);
        NSLog(@"现在是%ld分", comp.minute);
        NSLog(@"现在是%ld秒", comp.second);
        NSLog(@"现在是星期%ld", comp.weekday);
        //再次创建一个NSDateComponents对象
        NSDateComponents* comp2 = [[NSDateComponents alloc] init];
        //设置各时间段的数值
        comp2.year = 2021;
        comp2.month = 6;
        comp2.day = 1;
        comp2.hour = 10;
        comp2.minute = 23;
        //通过NSDateComponents所包含的各时间字段的数值来恢复NSDate对象
        NSDate* date = [gregorian dateFromComponents: comp2];
        NSLog(@"获取的日期为%@", date);
        
    }
    return 0;
}

输出结果:
在这里插入图片描述

定时器(NSTimer)

如果程序需要让某个方法重复执行,则可以借助OC的定时器来完成。具体步骤如下:

  1. 调用NSTimer的scheduledTimerWithTimeInterval:invonation:repeats: 或scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 类方法来创建NSTimer对象。调用该类方法时,需要传入以下参数:
  • timeInterval:指定每隔多少秒执行一次任务。
  • invocation或target与selector:指定重复执行的任务。如果指定target和selector参数,则指定用某个对象的特定方法作为重复执行任务;如果指定invocation参数,该参数需要传入一个NSInvocation对象,该NSInvocation对象也是封装target和selector的,其实也是指定某个对象的特定方法作为重复执行的任务。
  • userInfo:该参数用于传入额外的附加信息。
  • repeats:该参数需要指定一个BOOL值,该参数控制是否需要重复执行任务。
  1. 为第一步的任务编写方法。
  2. 销毁定时器。调用定时器的invalidate方法即可。

示例:

//  Timer.h

#import <Foundation/Foundation.h>

@interface Timer : NSObject {
    NSInteger _index;
    NSTimer* _timer;
}
-(void) startMyTimer;
-(void) stopMyTimer;
-(void)timerAction: (NSTimer*) timer;
@end
//  Timer.m

#import "Timer.h"
 
@implementation Timer
- (instancetype)init {
    if (self = [super init]) {
        _index = 10;
        [self startMyTimer];
    }
    return self;
}
 
- (void)startMyTimer {
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0
            target:self
            selector:@selector(timerAction:)
            userInfo:@"hello."
            repeats:YES];
}
 
- (void)stopMyTimer {
    [_timer invalidate];
    NSLog(@"倒计时结束");
}
 
- (void)timerAction:(NSTimer *)timer {
    _index--;
    NSLog(@"%li秒",_index);
    NSLog(@"%@",timer.userInfo);
    if (_index == 0) {
        [self stopMyTimer];
    }
}
@end
//  main.m

#import "Timer.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Timer* mytimer = [[Timer alloc] init];
        NSRunLoop *loop = [NSRunLoop currentRunLoop];
        [loop run];
    }
    return 0;
}

最后执行程序,每秒输出一次:
在这里插入图片描述

以上是关于OC Foundation框架 日期与时间的主要内容,如果未能解决你的问题,请参考以下文章

OC Foundation框架 集合

OC Foundation框架 数组

OC Foundation框架 对象复制

34-oc Foundation简介

OC 知识:Foundation 框架及相关类详尽总结

Foundation框架知识总结