美文网首页iOS
iOS 日期时间那点儿事儿

iOS 日期时间那点儿事儿

作者: 舌尖上的大胖 | 来源:发表于2018-04-01 15:14 被阅读236次

一、基本约定及要素

现代系统对于日期时间的处理思想,是系统统一以 UTC 时间为准。在需要时,根据时区、日历、国际化/本地化等设置,依据 UTC 时间计算出所需要的时间,用于显示等操作。所以,理论上,世界上任何一台电脑,只要时钟是准的,获取到的 UTC 时间是一致的。只是系统会根据我们在电脑中设定的时区、日历、国际化/本地化等信息,再进行展示。
  iOS 中,主要涉及到的类如下:

  • NSDate
    主要用于日期的获取、存储、计算
  • NSDateComponents
    工具类,用于对于日期、时间的拆分、组装
  • NSCalendar
    日历,通过指定不同日历类型,来获取对应的信息。如:获取当前时间的农历月、日信息。
  • NSLocale
    区域化相关内容。此类不仅用于日期时间,本文只涉及日期时间的部分。
    如:获取当前时间月份的名称,区域为美国会显示 May,区域为中国会显示五月
  • NSTimeZone
    时区。用于配合 UTC 时间计算指定的时区对应的时间。
  • NSDateFormatter
    日期、时间格式化工具。格式化时,会根据用户指定的格式、时区、地区,进行处理。

二、一些综合应用

1、从字符串转化为时间

有些场景需要根据存储的字符串转换回时间。比如:HTTP 的 Response Header 的 Date 字段,格式为:Sun, 01 Apr 2018 01:18:07 GMT,需要转换回 NSDate,才便于后续处理。

- (NSDate *)dateFromString:(NSString *)dateStr {
    // 创建日期格式化工具
    NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
    // 指定日期格式,如上所示:Sun, 01 Apr 2018 01:18:07 GMT
    dateFormatter.dateFormat = @"EEE',' dd' 'MMM' 'yyyy HH':'mm':'ss 'GMT'";
    // 指定区域,这个很重要!EEE、MMM 会根据区域设置进行处理。如果这里设置为中文,则只能处理 “四月”、“周日”,而不能处理 “Apr”、“Sun”
    dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en"];
    // 指定所使用的是 UTC 时间
    dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];

    return [dateFormatter dateFromString:dateStr];
}

根据当前时间,格式化输出,操作类似。

2、获取当前时间的公历、农历日期

- (void)showDate {
    // 当前日期
    NSDate *date = [NSDate date];

    // 创建公历日历,此为默认值
    NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
    // 获取月、日
    NSDateComponents *dateComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    NSLog(@"公历日期:%ld-%ld", dateComponents.month, dateComponents.day);

    // 创建中国农历日历
    calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierChinese];
    // 获取月、日
    dateComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    NSLog(@"农历日期:%ld-%ld", dateComponents.month, dateComponents.day);
}

3、计算时间间隔

测试代码块耗时,单位:纳秒

#import <mach/mach_time.h>

CGFloat BNRTimeBlock (void (^block)(void)) {
    // 获取计时基础信息
    mach_timebase_info_data_t info;
    if (mach_timebase_info(&info) != KERN_SUCCESS) return -1.0;

    // 开始时间
    uint64_t start = mach_absolute_time ();

    // 执行代码块
    block ();

    // 结束时间
    uint64_t end = mach_absolute_time ();

    // 计算时间差
    uint64_t elapsed = end - start;

    // 根据系统“心率”计算时间
    uint64_t nanos = elapsed * info.numer / info.denom;
    return (CGFloat)nanos / NSEC_PER_SEC;
} // BNRTimeBlock

除此方法外,可以采用更为方便的 CACurrentMediaTime(),返回单位为秒。这个是对 mach_absolute_time() 的封装,使用起来更方便一些。

三、备查资料

1、NSTimeZone 初始化

使用 + timeZoneWithName:
获取已知的有效时区名称:NSTimeZone.knownTimeZoneNames,返回数组

注:北京时间在 iOS 的 TimeZone 对照表里面并没有,使用上海时间代表中国标准时
采用如下方式初始化即可:

// 初始化时区为 上海时间
[NSTimeZone timeZoneWithName:@"Asia/Shanghai"];

使用 + timeZoneWithAbbreviation:
获取有效缩写:[NSTimeZone abbreviationDictionary],返回字典

2、NSCalendar 初始化

// 公历
NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
// 中国农历
calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierChinese];

具体日历类型,参见 NSCalendarIdentifier 类型。

3、NSDateFormatterStyle

typedef NS_ENUM(NSUInteger, NSDateFormatterStyle) {    // date and time format styles
    NSDateFormatterNoStyle = kCFDateFormatterNoStyle,
    NSDateFormatterShortStyle = kCFDateFormatterShortStyle,     // “11/23/37” or “3:30pm”.
    NSDateFormatterMediumStyle = kCFDateFormatterMediumStyle,   //“Nov 23, 1937”.or “3:30:32pm”.
    NSDateFormatterLongStyle = kCFDateFormatterLongStyle,       //“November 23, 1937” or “3:30:32pm”.  GMT+08:00
    NSDateFormatterFullStyle = kCFDateFormatterFullStyle        //“Tuesday, April 12, 1952 AD” or “3:30:42pm PST”.
};

这里假设的是区域设置为美国的情况,具体的格式,还跟 locale 设置有关。

常见 dateFormat
符号 说明
a AM/PM (上午/下午)
c/cc 1~7 (一周的第一天, 周日为1)
ccc Sun/Mon/Tue/Wed/Thu/Fri/Sat (星期几简写)
cccc Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday (星期几全拼)
d 1~31 (月份的第几天, 带0)
D 1~366 (年份的第几天,带0)
e 1~7 (一周的第几天, 带0)
E~EEE Sun/Mon/Tue/Wed/Thu/Fri/Sat (星期几简写)
EEEE Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday (星期几全拼)
F 1~5 (每月的第几周, 一周的第一天为周一)
h 1~12 (0 padded Hour (12hr)) 带0的时, 12小时制
H 0~23 (0 padded Hour (24hr)) 带0的时, 24小时制
m 0~59 (0 padded Minute) 分钟
M/MM 1~12 (0 padded Month) 第几月
MMM Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
MMMM January/February/March/April/May/June/July/August/September/October/November/December
s 0~59 (0 padded Second) 秒数
SSS (rounded Sub-Second) 毫秒
w 1~53 (0 padded Week of Year, 1st day of week = Sunday, NB: 1st week of year starts from the last Sunday of last year) 一年的第几周, 一周的开始为周日,第一周从去年的最后一个周日起算
W 1~5 (0 padded Week of Month, 1st day of week = Sunday) 一个月的第几周
y/yyyy (Full Year) 完整的年份
yy/yyy (2 Digits Year) 2个数字的年份
Y/YYYY (Full Year, starting from the Sunday of the 1st week of year) 这个年份未知干嘛用的
YY/YYY (2 Digits Year, starting from the Sunday of the 1st week of year) 这个年份未知干嘛用的
z~zzz (Specific GMT Timezone Abbreviation) 指定GMT时区的编写
zzzz (Specific GMT Timezone Name) Z: +0000 (RFC 822 Timezone) 指定GMT时区的名称

详见
Date Format Patterns
Date Field Symbol Table

4、时间进制换算

1 秒(s) == 1000 毫秒(ms)
1 毫秒(ms) == 1000 微秒(μs)
1 微秒(μs) == 1000 纳秒(ns)

四、参考资料

(完)

相关文章

  • iOS 日期时间那点儿事儿

    一、基本约定及要素 现代系统对于日期时间的处理思想,是系统统一以 UTC 时间为准。在需要时,根据时区、日历、国际...

  • iOS日期时间排序

    array = (NSMutableArray *)[array sortedArrayUsingComparat...

  • iOS - 时间日期

    NSDate时间->GTM(国际标准时间) NSTimeInterval时间间隔单位是秒 NSDateFormat...

  • iOS 关于加密那点儿事儿

    這篇文章關於加密寫的很詳細 www.cocoachina.com/ios/20151231/14835.html

  • iOS NSDate 时间日期

    近来用到时间空间,整理一些可能用到的处理NSDate的方法和大家分享,有什么不足的欢迎大家补充。 //获取当前时间...

  • iOS 时间日期总结

    获取时间戳 单位秒,保留六位有效数字,格式如:1574068247.545103 单位秒,整数,格式如:15740...

  • iOS 截图的那些事儿

    iOS 截图的那些事儿 iOS 截图的那些事儿

  • 时间与日期

    在iOS原生类中用以处理时间与日期的类:NSCalendar 日历处理NSDateComponents 将日期进...

  • iOS 时间戳转时间 日期 星期

    在开发中,往往我们会用到时间戳这个东西,至于时间戳是个什么东西,我就不去多说了,因为百度上很多。好了,今天我和大家...

  • 兼容性问题

    iOS设备 日期字符串转日期后显示NaN iOS系统不支持2017-01-01格式的时间,只识别2017/01/0...

网友评论

    本文标题:iOS 日期时间那点儿事儿

    本文链接:https://www.haomeiwen.com/subject/oltacftx.html