时间字符串与date转化, 利用NSDateFormatter
常用格式例如: @"2016-01-29 22:20:02" 转date
- (void)str2Date
{
NSString *strDate = @"2016-01-29 22:20:02";
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *date = [fmt dateFromString:strDate];
NSLog(@"%@", date);
}
- log结果:2016-01-29 14:20:02 +0000
date转字符串:
- (void)date2Str
{
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy/MM/dd : HH:mm:ss";
NSString *strDate = [fmt stringFromDate:[NSDate date]];
NSLog(@"%@", strDate);
}
- log结果:2016/01/30 : 22:17:19
- 常用日期格式符:
- yyyy:year
- MM:month
- dd:day
- HH:24小时制, hh12小时制
- mm:minute
- ss:second
- 字符串转date, 只要将对应的数值替代为对应的格式符就行了
- date转字符串:系统只会将对应格式符的数值替代格式符的位置, 你自定义用来连接日期的的其他符号没有任何影响,所以你也可以这样写: @"MM/dd yyyy : HH:mm:ss”, 或者只写其中某一部分都行:@“HH:mm”
你可能还会遇到这样的格式:@"Tue Sep 28 17:46:55 +0800 2011"
- (void)str2Date_locale
{
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"];
fmt.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy";
NSDate *date = [fmt dateFromString:@"Tue Sep 28 17:46:55 +0800 2011"]; // 国际通用时间的格式
NSLog(@"%@", date);
}
- log:2011-09-28 09:46:55 +0000
- 这几个格式你还需要知道:
- MMM:表示其中的Sep, 后面MM表示month, 跟前面一样, 前面一个M表示这种格式的月份
- 拓展:M:9, MM:09, MMM:Sep, MMMM:September
- EEE:代表week, Tuesday
- 拓展:EEE:Tue, EEEE:Tuesday, EEEEE:T
- Z, 代表时区, + 是东时区, - 是西时区
- 这种国际比较通用的时间格式, 一般最好统一时间格式的locale
将本地化修改为en_US
时间戳, @"1231234343433”, 这种时间格式的含义是距离1970年, 经过了多长时间
- (void)string2DataUseShijianchuo
{
NSString *strDate = @"1231234343433";// 时间戳, 单位毫秒, 表示从1970年开始经过了多少时间
NSDate *date = [NSDate dateWithTimeIntervalSince1970:strDate.doubleValue / 1000];
NSLog(@"%@", date);
}
- log:2009-01-06 09:32:23 +0000
NSDate比较
- 对时间比较以及求时间差等, 一般将时间转为NSDate, 在处理时更方便
粗略的比较用compare这个方法
- 巧记
- Descending, 从左到右降序, 消极的
- Ascending, 从左到右升序, 积极的
- (void)compare
{
NSString *createdAtString = @"2016-01-29 10:18:01";
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *createDate = [fmt dateFromString:createdAtString];
NSDate *curDate = [NSDate date];
NSComparisonResult res = [createDate compare:curDate];
if (res == NSOrderedDescending) {
NSLog(@"降序");// 左边大于右边
}else if (res == NSOrderedAscending){
NSLog(@"升序");// 左边小于右边
}else if (res == NSOrderedSame){
NSLog(@"相等");// 相等
}
NSLog(@"%zd, %@, %@", res, createDate, curDate);
}
date的比较和服务器返回字符串时间自定义格式化显示
计算两个date的时间差
- (void)delta
{
// 日期格式化对象
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
// 设置日期格式
fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";
// 2个日期对象
NSDate *date1 = [fmt dateFromString:@"2016-01-29 10:18:01"];
NSDate *date2 = [fmt dateFromString:@"2016-02-02 11:22:45"];
NSInteger timeInterval = [date2 timeIntervalSinceDate:date1];
// 将时间差转化为对应的时分秒...
// 1分钟 = 60秒
NSInteger secondsPerMinute = 60;
// 1小时 = 60 * 60秒 = 3600秒
NSInteger secondsPerHour = 60 * secondsPerMinute;
// 1天 = 24 * 60 * 60秒
NSInteger secondsPerDay = 24 * secondsPerHour;
NSInteger day = timeInterval / secondsPerDay;
NSInteger hour = (timeInterval % secondsPerDay) / secondsPerHour;
NSInteger minute = ((timeInterval % secondsPerDay) % secondsPerHour) / secondsPerMinute;
NSInteger second = timeInterval % secondsPerMinute;
NSLog(@"%zd天%zd小时%zd分%zd秒", day, hour, minute, second);
}
- log: 4天1小时4分44秒
- 可以将上面的方法抽成NSdate的分类,因为返回值有很多, 所以我们考略用集合类型作为方法返回值, 不过这样也比较麻烦
- 还可以考虑用结构体作为返回值, 比集合类型号, 但结构体只能是基本数据类型, 通用性不高, 最后我们考虑用模型来保存返回值, 给模型定义多个属性, 这样通用性更高, 也更灵活
将上面的功能抽分类:
- 开发中我们将常需要对日期进行比较, 所以我们再提供几个方法:
.h文件
@interface JJTimeInterval : NSObject
/** 天 */
@property (nonatomic, assign) NSInteger day;
/** 小时 */
@property (nonatomic, assign) NSInteger hour;
/** 分钟 */
@property (nonatomic, assign) NSInteger minute;
/** 秒 */
@property (nonatomic, assign) NSInteger second;
@end
@interface NSDate (JJTimeInterval)
- (JJTimeInterval *)jj_timeIntervalSince:(NSDate *)date;
/**
* 是否为今天
*/
- (BOOL)jj_isInToday;
/**
* 是否为昨天
*/
- (BOOL)jj_isInYesterday;
/**
* 是否为明天
*/
- (BOOL)jj_isInTomorrow;
/**
* 是否为今年
*/
- (BOOL)jj_isInThisYear;
@end
- 实现jj_timeIntervalSince:方法
- 注意:
-
NSCalendar currentCalendar
是以前的方法, 有时会有一些bug, 最好用下面这个方法, 但这个方法是iOS_8才有的, 所以要适配
+ (instancetype)jj_calendar
{
if ([self respondsToSelector:@selector(calendarWithIdentifier:)]) {
return [self calendarWithIdentifier:NSCalendarIdentifierGregorian];
}
return [self currentCalendar];
}
- 不能仅仅判断cmp.year == 0 && cmp.month == 0 && cmp.day == 0, 该方法会结合时分秒,如果时间差在24小时内, 就算差一天, 而我们的需求是, 只要日期day的数字差一天就算差一天, 相同则为同一天, 所以要剔除时分秒的影响
.m文件
@implementation JJTimeInterval
@end
@implementation NSDate (JJTimeInterval)
- (JJTimeInterval *)jj_timeIntervalSince:(NSDate *)date
{
JJTimeInterval *timeInterval = [[JJTimeInterval alloc] init];
NSInteger interval = [self timeIntervalSinceDate:date];
// 将时间差转化为对应的时分秒...
// 1分钟 = 60秒
NSInteger secondsPerMinute = 60;
// 1小时 = 60 * 60秒 = 3600秒
NSInteger secondsPerHour = 60 * secondsPerMinute;
// 1天 = 24 * 60 * 60秒
NSInteger secondsPerDay = 24 * secondsPerHour;
timeInterval.day = interval / secondsPerDay;
timeInterval.hour = (interval % secondsPerDay) / secondsPerHour;
timeInterval.minute = ((interval % secondsPerDay) % secondsPerHour) / secondsPerMinute;
timeInterval.second = interval % secondsPerMinute;
return timeInterval;
}
- (BOOL)jj_isInToday
{
// 不呢仅仅判断cmp.year == 0 && cmp.month == 0 && cmp.day == 0, 该方法会结合时分秒,如果时间差在24小时内, 就算差一天, 而我们的需求是, 只要日期day差一天就算差一天, 相同则为同一天, 所以要提出时分秒的影响
NSCalendar *calendar = [NSCalendar jj_calendar];
NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSDateComponents *selfCmp = [calendar components:unit fromDate:self];
NSDateComponents *nowCmp = [calendar components:unit fromDate:[NSDate date]];
if ([selfCmp isEqual:nowCmp]) {
return YES;
}
return NO;
}
- (BOOL)jj_isInTomorrow
{
NSCalendar *calendar = [NSCalendar jj_calendar];
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyyMMdd";
NSString *selfStr = [fmt stringFromDate:self];
NSString *nowStr = [fmt stringFromDate:[NSDate date]];
// 获得只有年月日的格式化date
NSDate *selfDate = [fmt dateFromString:selfStr];
NSDate *nowDate = [fmt dateFromString:nowStr];
NSDateComponents *cmp = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0];
if (cmp.day == 1) {
return YES;
}
return NO;
}
- (BOOL)jj_isInYesterday
{
// 注意deltaDay == -1, deltaMonth == 0,deltaYear == 0, | 注意deltaDay == 1, deltaMonth == 0,deltaYear == 0, 并不能表示,一定是昨天或明天
NSCalendar *calendar = [NSCalendar jj_calendar];
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyyMMdd";
NSString *selfStr = [fmt stringFromDate:self];
NSString *nowStr = [fmt stringFromDate:[NSDate date]];
// 获得只有年月日的格式化date
NSDate *selfDate = [fmt dateFromString:selfStr];
NSDate *nowDate = [fmt dateFromString:nowStr];
NSDateComponents *cmp = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0];
if (cmp.day == -1) {
return YES;
}
return NO;
}
- (BOOL)jj_isInThisYear
{
NSCalendar *calendar = [NSCalendar jj_calendar];
NSCalendarUnit unit = NSCalendarUnitYear;
NSDateComponents *selfCmp = [calendar components:unit fromDate:self];
NSDateComponents *nowCmp = [calendar components:unit fromDate:[NSDate date]];
if ([selfCmp isEqual:nowCmp]) {
return YES;
}
return NO;
}
@end
应用
- created____at是模型时间, 用我们的分类, 得到我们想要的时间
- 判断逻辑:优先判断今天昨天,然后再是今年去年
- (NSString *)formatCreated_at:(JJTopic *)topic
{
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *create_atDate = [fmt dateFromString:topic.created_at];
JJTimeInterval *timeInterval = [create_atDate jj_timeIntervalSince];
if ([create_atDate jj_isInToday]) {
if (timeInterval.hour !=0) {
return [NSString stringWithFormat:@"%ld小时前", timeInterval.hour];
}else if (timeInterval.minute != 0){
return [NSString stringWithFormat:@"%ld分钟前", timeInterval.minute];
}else{
return [NSString stringWithFormat:@"刚刚"];
}
}else if([create_atDate jj_isInYesterday]){
fmt.dateFormat =@"HH:mm:ss";
return [NSString stringWithFormat:@"昨天:%@", [fmt stringFromDate:create_atDate]];
}else if ([create_atDate jj_isInThisYear]){
fmt.dateFormat = @"MM-dd HH:mm:ss";
return [NSString stringWithFormat:@"%@", [fmt stringFromDate:create_atDate]];
}else{
return topic.created_at;
}
return nil;
}
屏幕快照 2016-01-31 下午10.29.51.png
写的不好,下篇写上下拉刷新的实现, 不过过年也许就不写了...
网友评论