iOS学习笔记37-时间和日期计算

一、时间和日期计算

我们在应用开发中,时常须要和时间打交道,比方获取当前时间,获取两个时间点相隔的时间等等,在iOS开发中与时间相关的类有例如以下几个:
1. NSDate:表示一个绝对的时间点
2. NSTimeZone:时区信息
3. NSLocale:本地化信息
4. NSDateComponents:一个封装了具体年月日、时秒分、周、季度等的类
5. NSCalendar:日历类,它提供了大部分的日期计算接口
6. NSDateFormatter:用来在日期和字符串之间转换

二、NSDate时间点

NSDate存储的是世界标准时(UTC),输出时须要依据时区转换为本地时间

NSDate经常使用初始化方法:
/* 获取当前时间,alloc/init得到的时间也是当前时间 */+ (instancetype)date;/* 以当前时间为基准,获取偏移秒数的时间 */+ (instancetype)dateWithTimeIntervalSinceNow:(NSTimeInterval)seconds;/* 以1970年1月1日为基准。获取偏移秒数的时间 */+ (instancetype)dateWithTimeIntervalSince1970:(NSTimeInterval)seconds;/* 以2001年1月1日为基准。获取偏移秒数的时间 */+ (instancetype)dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)seconds;/* 以指定时间点为基准。获取偏移秒数的时间 */+ (instancetype)dateWithTimeInterval:(NSTimeInterval)seconds  sinceDate:(NSDate *)date;/* 获取一个极早的时间点,0001-12-30 00:00:00 +0000 */+ (instancetype)distantPast;/* 获取一个极晚的时间点,4001-01-01 00:00:00 +0000 */+ (instancetype)distantFuture;
  • 除了最后的2个获取极早极晚时间的方法,其他方法都有相应的init前缀方法。

  • 极早和极晚时间经常使用于定时器的開始和暂停
  • 偏移秒数为正。表示比基准时间晚的时间,偏移秒数为负,表示比基准时间早的时间
NSDate经常使用的对象方法:
/* 以当前NSDate对象为基准,获取偏移指定秒数后得到的新NSDate对象 */- (instancetype)dateByAddingTimeInterval:(NSTimeInterval)seconds;#pragma mark - 比較2个时间/* 比較2个NSDate对象,返回较早的那个NSDate时间点对象 */- (NSDate *)earlierDate:(NSDate *)anotherDate;/* 比較2个NSDate对象,返回较晚的那个NSDate时间点对象 */- (NSDate *)laterDate:(NSDate *)anotherDate;/* 比較2个NSDate对象。返回枚举类型(相等、早于、晚于) */- (NSComparisonResult)compare:(NSDate *)anotherDate;#pragma mark - 获取相隔秒数,从參数时间開始,经过多少秒到达对象运行时间/* 返回当前对象时间与1970年1月1日00:00:00的相隔秒数 */- (NSTimeInterval)timeIntervalSince1970;/* 返回当前对象时间与2001年1月1日00:00:00的相隔秒数 */- (NSTimeInterval)timeIntervalSinceReferenceDate;/* 返回当前对象时间与当前client时间的相隔秒数 */- (NSTimeInterval)timeIntervalSinceNow;/* 返回当前对象时间与指定时间的相隔秒数 */- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate;
以下是使用实例:
/* 获取当前client时间 */NSDate *date1 = [NSDate date];/* 获取比date1晚30秒的时间 */NSDate *date2 = [NSDate dateWithTimeInterval:30 sinceDate:date1];/* 比較2个时间,获取较早的时间和较晚的时间 */NSDate *earlierDate = [date1 earlierDate:date2];NSDate *laterDate = [date1 laterDate:date2];NSLog(@"earlierDate:%@。laterDate:%@",earlierDate,laterDate);/* 比較2个时间 */NSComparisonResult result = [date1 compare:date2];switch(result){ case NSOrderedSame: NSLog(@"对象时间等于參数时间"); break; case NSOrderedAscending: NSLog(@"对象时间早于參数时间"); break; case NSOrderedDescending: NSLog(@"对象时间晚于參数时间"); break;}/* 获取相隔时间秒数,将返回结果-30,从date2的时间開始,倒退30秒到达date1的时间 */NSTimeInterval seconds = [date1 timeIntervalSinceDate:date2];NSLog(@"date1与date2相隔%@秒",seconds);

三、NSTimeZone时区

NSTimeZone经常使用初始化方法:
/* 依据时区名称初始化。比如:America/Chicago(美国芝加哥) */+ (instancetype)timeZoneWithName:(NSString *)aTimeZoneName;/* 依据时区缩写初始化,比如:EST(美国东部标准时间)、HKT(香港标准时间) */+ (instancetype)timeZoneWithAbbreviation:(NSString *)abbreviation;/* 返回系统时区 */+ (NSTimeZone *)systemTimeZone;/* 返回本地时区 */+ (NSTimeZone *)localTimeZone;
  • 时区名称能够通过以下方法获取:
/* 以数组形式返回全部已知的时区名称 */+(NSArray *)knownTimeZoneNames;
  • 本地时区和系统时区的差别在于本地时区能够被改动,而系统时区不能改动
NSTimeZone经常使用对象方法:
/* 获取时区名称 */- (NSString *)name;/* 获取时区缩写 */- (NSString *)abbreviation;/* 获取对象时区与零时区的间隔秒数 */- (NSInteger)secondsFromGMT;

四、NSLocale本地化信息

NSLocale类返回本地化信息。主要体如今语言区域格式这两个设置项。

NSLocale经常使用初始化方法:
/* 返回系统初始本地化信息 */+(instancetype)systemLocale;/* 返回当前client的本地化信息。即使改动了本地化设定,这个对象也不会改变 */+(instancetype)currentLocale;/* 返回当前client的本地化信息,当每次改动本地化设定,事实上例化的对象会随之改变 */+(instancetype)autoupdatingCurrentLocale;/* 用标示符初始化本地化信息。比如:en_US */-(instancetype)initWithLocaleIdentifier:(NSString *)string;
NSLocale经常使用对象方法:
/* 依据不同的key返回各种本地化信息 */- (id)objectForKey:(id)key;/* 显示特定地区代号下相应键的显示名称 */- (NSString *)displayNameForKey:(id)key value:(id)value;
以下是使用实例:
//获取系统本地化信息NSLocale *sysLocale = [NSLocale systemLocale];//获取client本地化信息,不可响应改动NSLocale *curLocale = [NSLocale currentLocale];//获取client本地化信息,可动态响应改动NSLocale *autoCurLocale = [NSLocale autoupdatingCurrentLocale];//通过标识创建自己定义本地化信息NSLocale *userLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];//获取货币符号NSString *strSymbol = [userLocale objectForKey:NSLocaleCurrencySymbol];NSLog(@"货币符号:%@",strSymbol);//打印:¥//获取本地日历NSCalendar *calendar = [userLocale objectForKey:NSLocaleCalendar];NSLog(@"本地日历:%@",calendar);//得到"en_US"的NSLocaleIdentifier键的显示名称NSString *str = [userLocale displayNameForKey:NSLocaleIdentifier value:@"en_US"];NSLog(@"标识显示名称:%@",str);//打印:英文(美国)

五、NSDateComponents时间封装

NSDateComponents封装了具体年月日、时秒分、周、季度等:

/* 创建一个日期对象 */NSDateComponents*compt = [[NSDateComponents alloc] init];[compt setEra:1];//纪元[compt setYear:2013];//年[compt setMonth:3];//月[compt setDay:15];//日[compt setHour:11];//小时[compt setMinute:20];//分钟[compt setSecond:55];//秒钟[compt setQuarter:2];//几刻钟[compt setTimeZone:[NSTimeZone systemTimeZone]];//时区[compt setWeek:3];//一年的第几周[compt setWeekday:4];//周几[compt setWeekOfMonth:3];//一个月的第几周[compt setWeekOfYear:3];//一年的第几周[compt setCalendar:[NSCalendar currentCalendar]];//日历

NSDateComponents通常不单独使用。它经常与时间点NSDate、日历类NSCalendar一起使用

六、NSCalendar日历类

NSCalendar类,表示日历,封装了大量的计算日期方法

NSCalendar经常使用创建方法:
/* 返回client的逻辑日历,即使改动了系统日历设定,这个对象也不会改变 */+(instancetype)currentCalendar;/* 返回client的逻辑日历,改动了系统日历设定。这个对象会随之改变 */+(instancetype)autoupdatingCurrentCalendar;/* 依据提供的日历标示符初始化 */-(instancetype)initWithCalendarIdentifier:(NSString *)string;
系统中定义的日历标识符有:
  • NSGregorianCalendar:公历
  • NSBuddhistCalendar:佛教日历
  • NSChineseCalendar:中国农历
  • NSHebrewCalendar:希伯来日历
  • NSIslamicCalendar:伊斯兰历
  • NSIslamicCivilCalendar:伊斯兰教日历
  • NSJapaneseCalendar:日本日历
  • NSRepublicOfChinaCalendar:中华民国日历(台湾)
  • NSPersianCalendar:波斯历
  • NSIndianCalendar:印度日历
  • NSISO8601Calendar:ISO8601日历
NSCalendar经常使用的与NSDateComponents相关对象方法:
/* 取得一个NSDate对象的1个或多个部分转为NSDateComponents, 仅仅有明白指定了unitFlags。NSDateComponents相应的那一部分才有值 */- (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)date;/* 取得两个NSDate对象的时间间隔,用NSDateComponents来封装 */- (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate*)resultDate options:(NSUInteger)opts;/* 一般默认传0就可以 *//* 依据NSDateComponents对象得到一个NSDate对象 */- (NSDate *)dateFromComponents:(NSDateComponents *)comps;/* 在參数date基础上,添加一个NSDateComponents类型的时间增量 */- (NSDate *)dateByAddingComponents:(NSDateComponents *)comps toDate:(NSDate *)date options:(NSUInteger)opts;/* 一般默认传0就可以 */

unitFlags參数通过以下的日历单位NSCalendarUnit用或运算“|”组合使用

日历单位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:星期单位。每周的7天。范围为1-7
  • NSWeekdayOrdinalCalendarUnit:没全然搞清楚
  • NSQuarterCalendarUnit:几刻钟,也就是15分钟。范围为1-4
  • NSWeekOfMonthCalendarUnit:月包括的周数。最多为6个周
  • NSWeekOfYearCalendarUnit:年包括的周数。

    最多为53个周

  • NSYearForWeekOfYearCalendarUnit:没全然搞清楚
  • NSTimeZoneCalendarUnit:没全然搞清楚
以下是使用实例:
//获取client逻辑日历NSCalendar *calendar = [NSCalendar currentCalendar];//获取当前时间NSDate *date = [NSDate date];//从date中读取年月日。存储在NSDateComponents对象中NSDateComponents *compt1 = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];NSLog(@"年:%d",[compt1 year]);//2016NSLog(@"月:%d",[compt1 month]);//4NSLog(@"日:%d",[compt1 day]);//19/*********************************************************************///创建一个时间相差5小时1分15秒的时间点NSDate *date2 = [NSDate dateWithTimeInterval:5*60*60+1*60+15 sinceDate:date];//时间间隔NSDate转NSDateComponents,分钟加秒钟NSDateComponents *compt2 = [calendar components:(NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:date toDate:date2 options:0];NSLog(@"时间间隔【分种加秒钟】:%d分%d秒",[compt2 minute],[compt2 second]);//301分15秒//时间间隔NSDate转NSDateComponents,仅仅有秒钟NSDateComponents *compt3 = [calendar components:NSSecondCalendarUnit fromDate:date toDate:date2 options:0];NSLog(@"时间间隔【秒数】:%d秒",[compt3 second]);//18075秒/*********************************************************************///创建自己定义NSDateComponents对象NSDateComponents *compt4 = [[NSDateComponents alloc] init];[compt4 setYear:2012];[compt4 setMonth:5];[compt4 setDay:11];//NSDateComponents对象转NSDate对象NSDate *newDate = [calendar dateFromComponents:compt4];//得到本地时间,避免时区问题NSTimeZone *zone = [NSTimeZone systemTimeZone];NSInteger interval = [zone secondsFromGMTForDate:newDate];NSDate *localeDate = [newDate dateByAddingTimeInterval:interval];NSLog(@"NSDateComponents对象转NSDate对象:%@",localeDate);/*********************************************************************///创建自己定义NSDateComponents对象NSDateComponents *compt5 = [[NSDateComponents alloc] init];[compt5 setDay:25];[compt5 setHour:4];[compt5 setMinute:66];NSDate *addDate = [calendar dateByAddingComponents:compt5 toDate:[NSDate date] options:0];//得到本地时间。避免时区问题NSTimeZone *zone2 = [NSTimeZone systemTimeZone];NSInteger interval2 = [zone2 secondsFromGMTForDate:addDate];NSDate *localeDate2 = [addDate dateByAddingTimeInterval:interval2];NSLog(@"NSDate对象追加NSDateComponents对象时间:%@",localeDate2);
NSCalendar类另一些日历设置和计算的方法:
/* 设置本地化信息 */- (void)setLocale:(NSLocale *)locale;/* 设置时区信息 */- (void)setTimeZone:(NSTimeZone *)tz;/* 设置每周的第一天是从星期几開始,1表示是星期天(默认)。2表示星期一。以此类推 */- (void)setFirstWeekday:(NSUInteger)weekday;/* 设置每年及每月第一周必须包括的最少天数,比方:设定第一周最少包括3天。则value传入3 */- (void)setMinimumDaysInFirstWeek:(NSUInteger)value;/* 获取一个小的单位在一个大的单位里面的序数 */- (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;/* 依据參数提供的时间点。得到一个小的单位在一个大的单位里面的取值范围 */- (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date;/* 依据參数提供的时间点,返回所在日历单位的開始时间。

假设startDate和interval都计算得出来。则返回YES。否则返回NO */ - (BOOL)rangeOfUnit:(NSCalendarUnit)unit /* 日历单位 */ startDate:(NSDate **)datep /* 開始时间。通过參数返回 */ interval:(NSTimeInterval *)tip /* 日历单位所相应的秒数。通过參数返回 */ forDate:(NSDate *)date; /* 时间点參数 */

七、NSDateFormatter字符串格式化

NSDateFormatter专门负责时间NSDate和字符串NSString之间的转换

以下是格式化符使用规定:
  • 大写G:纪元
    通常会显示公元前(BC)和公元(AD)
  • 小写y:年
    假如是2013年。那么yyyy=2013,yy=13
  • 大写M:月
    假如是3月,那么M=3,MM=03,MMM=Mar,MMMM=March
    假如是11月,那么M=11。MM=11。MMM=Nov。MMMM=November
  • 小写w:年包括的周
    假如是1月8日。那么w=2(这一年的第二个周)
  • 大写W:月份包括的周(与日历排列有关)
    假如是2013年4月21日。那么W=4(这个月的第四个周)
  • 大写F:月份包括的周(与日历排列无关)
    和上面的W不一样,F仅仅是单纯以7天为一个单位来统计周。比如7号一定是第一个周。15号一定是第三个周,与日历排列无关。

  • 大写D:年包括的天数
    假如是1月20日。那么D=20(这一年的第20天)
    假如是2月25日,那么D=31+25=56(这一年的第56天)
  • 小写d:月份包括的天数
    假如是5号。那么d=5。dd=05
    假如是15号,那么d=15,dd=15
  • 大写E:星期
    假如是星期五,那么E=Fri。EEEE=Friday
  • 小写a:上午(AM)/下午(PM)
  • 大写H:24小时制。显示为0–23
    假如是午夜00:40,那么H=0:40,HH=00:40
  • 小写h:12小时制,显示为1–12
    假如是午夜00:40,那么h=12:40
  • 大写K:12小时制,显示为0–11
    假如是午夜00:40。那么K=0:40,KK=00:40
  • 小写k:24小时制,显示为1–24
    假如是午夜00:40。那么k=24:40
  • 小写m:分钟
    假如是5分钟。那么m=5,mm=05
    假如是45分钟。那么m=45。mm=45
  • 小写s:秒
    假如是5秒钟。那么s=5。ss=05
    假如是45秒钟,那么s=45。ss=45
  • 大写S:毫秒
    一般用SSS来显示
  • 小写z:时区
    表现形式为GMT+08:00
  • 大写Z:时区
    表现形式为+0800
以下是使用范例:
//创建日期字符串格式化器NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; //设置时区 [formatter setTimeZone:[NSTimeZone systemTimeZone]];//设置格式化输出格式[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];//创建时间NSDateComponents *compt = [[NSDateComponents alloc] init]; [compt setYear:2013]; [compt setMonth:3]; [compt setDay:13]; [compt setHour:1]; [compt setMinute:55]; [compt setSecond:28]; //获取日历对象 NSCalendar *calendar = [NSCalendar currentCalendar]; //设置时区 [calendar setTimeZone:[NSTimeZone systemTimeZone]];//NSDateComponents对象转NSDate对象NSDate *date = [calendar dateFromComponents:compt];NSLog(@"date:%@",date);//格式化输出字符串,传入要格式化的时间NSDate对象NSString *str = [formatter stringFromDate:date];NSLog(@"格式化输出:%@",str);
具体介绍能够參考这里。讲得非常具体:wayne23的博客
假设有什么问题能够在下方评论区中提出。O(∩_∩)O哈!

$(function () {
$(‘pre.prettyprint code‘).each(function () {
var lines = $(this).text().split(‘\n‘).length;
var $numbering = $(‘

    ‘).addClass(‘pre-numbering‘).hide();
    $(this).addClass(‘has-numbering‘).parent().append($numbering);
    for (i = 1; i <= lines; i++) {
    $numbering.append($(‘

  • ‘).text(i));
    };
    $numbering.fadeIn(1700);
    });
    });

相关文章