iOS日期处理

服务器返回的时间是字符串,手机获取的时间是NSDate,需要进行转换。

凡是日期处理,这三个类足够了

  • NSDate
  • NSDateFormatter
  • NSCalendar

NSDate


// 获取当前时间(0时区)
NSDate *now = [NSDate date];

NSDateFormatter


NSDateFormatter类的作用

NSString * -> NSDate *
NSDate * -> NSString *

NSString -> NSDate

  1. 创建日期格式化类
  2. 设置日期格式
  • 如果是欧美时间,设置语言代码
  1. NSString转NSDate

服务器返回的是普通格式时间

// 时间字符串
NSString *string = @"2015-12-10 19:25:07";

// 日期格式化对象
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];

// 日期格式
fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";

// NSString -> NSDate
NSDate *date = [fmt dateFromString:string];

服务器返回的是欧美时间

在iOS中设置欧美日期,需要设置语言区域

// 时间字符串
NSString *string = @"Tue May 31 17:46:55 +0800 2011";

// 日期格式化对象
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];

// 日期格式
fmt.dateFormat = @"EEE MMM dd HH:mm:SS Z yyyy";
// 语言代码
fmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

// NSString -> NSDate
NSDate *date = [fmt dateFromString:string];
```

###服务器返回的是时间戳
- 时间戳:从1970-01-01 00:00:00开始走过的毫秒数

```objc
// iOS中接收的参数是秒,需要将时间戳的毫秒转成秒
[NSDate dateWithTimeIntervalSince1970:string.longLongValue / 1000.0];
```

##NSData -> NSString
```objc
// 日期对象
NSDate *date = [NSDate date];

// 日期格式化对象
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];

// 日期格式
fmt.dateFormat = @"yyyy年MM月dd日 HH:mm:ss";

// NSDate -> NSString
NSString *string = [fmt stringFromDate:date];
```
不论是NSString转NSDate,还是NSDate转NSString,进行转换时候,都需要`设置格式`。

##日期比较

###两个NSDate之间大小比较
```objc
/*
 NSComparisonResult取值
 NSOrderedAscending = -1L, 升序(右>左)
 NSOrderedSame, 相同
 NSOrderedDescending, 降序(右<左)
*/
NSComparisonResult result = [nowDate compare:createdAtDate];

switch (result) {
    case NSOrderedSame:
        NSLog(@"equal");
        break;
    case NSOrderedAscending:
        NSLog(@"now < createdAt");
        break;
    case NSOrderedDescending:
        NSLog(@"now > createdAt");
        break;
        
    default:
        break;
}
```

###获取时间间隔差值
```objc
// 手机当前时间和1970年的时间间隔(s)
NSDate *nowDate = [NSDate date];
NSTimeInterval interval = [nowDate timeIntervalSince1970];

// 手机当前事件和createdAtDate之间的时间间隔(s)
NSTimeInterval interval = [nowDate timeIntervalSinceDate:createdAtDate];
```
获取两个时间间隔之后,想要转换成自然语言时间间隔,需要经过计算,考虑到可能会有很多地方要用,抽取成分类
```objc
#import <Foundation/Foundation.h>

// 一次返回多个相关联的值,直接用模型封装
@interface XYDateItem : NSObject
@property (nonatomic, assign) NSInteger day;
@property (nonatomic, assign) NSInteger hour;
@property (nonatomic, assign) NSInteger minute;
@property (nonatomic, assign) NSInteger second;
@end

@interface NSDate (XYExtension)
- (XYDateItem *)xy_timeIntervalSinceDate:(NSDate *)date;
@end


#import "NSDate+XYExtension.h"

static int const secondPerMinute = 60;
static int const secondPerHour = 60 * 60;
static int const secondPerDay = 60 * 60 * 24;

@implementation XYDateItem

- (NSString *)description
{
    return [NSString stringWithFormat:@"%zd天%zd小时%zd分%zd秒", self.day, self.hour, self.minute, self.second];
}
@end

@implementation NSDate (XYExtension)

- (XYDateItem *)xy_timeIntervalSinceDate:(NSDate *)date
{
    // self和date的时间间隔
    NSTimeInterval interval = [self timeIntervalSinceDate:date];
    // 转成整型
    int intInterval = interval;
    
    XYDateItem *item = [[XYDateItem alloc] init];
    
    item.day = intInterval / secondPerDay;
    item.hour = (intInterval % secondPerDay) / secondPerHour;
    item.minute = ((intInterval % secondPerDay) % secondPerHour) / secondPerMinute;
    item.second = ((intInterval % secondPerDay) % secondPerHour) % secondPerMinute;
    
    return item;
}
@end
```

#NSCalendar
---
通过NSCalendar类可以获取日期的各种元素

##获取日期某个元素(iOS8之后)
```objc
- (NSInteger)component:(NSCalendarUnit)unit fromDate:(NSDate *)date
```
##获取日期元素
```objc
// unit传入什么值,就获取到什么元素,没传入的不获取
- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)date;
```

##计算两个NSDate之间的时间间隔
```objc
- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSCalendarOptions)opts;
```

##判断是不是在某一范围
如判断NSDate数据是不是今天/昨天/明天/周末等等
- iOS8之后NSCalendar自带方法

```objc
// NSCalendar自带方法, iOS8开始
- (BOOL)isDateInToday:(NSDate *)date
- (BOOL)isDateInYesterday:(NSDate *)date
- (BOOL)isDateInTomorrow:(NSDate *)date
- (BOOL)isDateInWeekend:(NSDate *)date
```

- iOS8之前自己写方法

```objc
/** 是不是今天 */
- (BOOL)xy_isToday
{
    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
    fmt.dateFormat = @"yyyyMMdd";
    
    NSString *selfString = [fmt stringFromDate:self];
    NSString *nowString = [fmt stringFromDate:[NSDate date]];

    return [selfString isEqualToString:nowString];
}

/** 是不是昨天 */
- (BOOL)xy_isYesterday
{
    NSDateFormatter  *fmt = [[NSDateFormatter alloc] init];
    fmt.dateFormat = @"yyyyMMdd";

    // 生成只有年月日的字符串
    NSString *selfString = [fmt stringFromDate:self];
    NSString *nowString = [fmt stringFromDate:[NSDate date]];
    
    // 生成只有年月日的日期对象
    NSDate *selfDate = [fmt dateFromString:selfString];
    NSDate *nowDate = [fmt dateFromString:nowString];
    
    NSCalendar *calendar = [NSCalendar xy_calendar];
    NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    NSDateComponents *cmps = [calendar components:unit fromDate:selfDate toDate:nowDate options:0];
    
    return cmps.year == 0
    && cmps.month == 0
    && cmps.day == 1;
}

/** 是不是明天 */
- (BOOL)xy_isTomorrow
{
    NSDateFormatter  *fmt = [[NSDateFormatter alloc] init];
    fmt.dateFormat = @"yyyyMMdd";
    
    // 生成只有年月日的字符串
    NSString *selfString = [fmt stringFromDate:self];
    NSString *nowString = [fmt stringFromDate:[NSDate date]];
    
    // 生成只有年月日的日期对象
    NSDate *selfDate = [fmt dateFromString:selfString];
    NSDate *nowDate = [fmt dateFromString:nowString];
    
    NSCalendar *calendar = [NSCalendar xy_calendar];
    NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
    NSDateComponents *cmps = [calendar components:unit fromDate:selfDate toDate:nowDate options:0];
    
    return cmps.year == 0
    && cmps.month == 0
    && cmps.day == -1;
}
```

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

推荐阅读更多精彩内容

  • 目录: 1、字符串转换为日期; 2、时间戳转换为日期; 3、日期转换为字符串 4、获取日期中的年、月、日、时、分、...
    金鱼________阅读 654评论 0 3
  • GitHub: https://github.com/GardenerYunEmail: gardeneryun@...
    园丁云阅读 5,248评论 3 38
  • 日期处理 NSString 与 NSDate 转换使用NSDateFormatter 日期格式说明: yy: 年...
    着魔的毛豆阅读 515评论 0 1
  • 一、先定义一个全局变量的NSTimeInterval 复制代码 @interface ViewController...
    IOS_龙阅读 1,105评论 0 0
  • 名字一听就没有想看的欲望,奈何这部剧是阅片无数的姐姐强烈安利给我的,于是勉强打开瞅瞅,没想到一看,就连续三晚刷到凌...
    一颗胖胖臻阅读 1,787评论 0 0