美文网首页iOS开发实践iOS_小蟹专题IT圈
DateTools使用「日期工具库」

DateTools使用「日期工具库」

作者: LuisX | 来源:发表于2016-05-23 19:49 被阅读4962次
DateTools

准备:

DateTools_下载

DateTools

DateTools是Objective-C中简化日期和时间处理的工具.

安装


CocoaPods
pod 'DateTools'

手动安装
DataTools所需的所有类包含在DataTools文件夹下,如下:

  • DateTools.h
  • NSDate+DateTools.{h,m}
  • DTConstants.h
  • DTError.{h,m}
  • DTTimePeriod.{h,m}
  • DTTimePeriodGroup.{h,m}
  • DTTimePeriodCollection.{h,m}
  • DTTimePeriodChain.{h,m}

如果你的工程想要支持国际化或者使用"TimeAgo"功能必须要导入bundle文件
你可以在工程中Info下添加Localizations来添加支持的语言

  • DateTools.bundle

DateTools.h 包含了所有其他文件的头文件.在你的工程中导入DateTools.h头文件即可

DateTools中包含3个子库

  • NSDate+DateTools
  • Time Periods
  • Time Period Groups

基本使用

NSDate+DateTools


1.Time Ago(相对日期形式)

Time ago 就是将日期转变为相对日期的形式,即我们常用的“昨天、今天、明天、几天前,一周以后……”这样的表述方式。

NSDate *timeAgoDate = [NSDate dateWithTimeIntervalSinceNow:-4];
NSLog(@"Time Ago: %@", timeAgoDate.timeAgoSinceNow);
NSLog(@"Time Ago: %@", timeAgoDate.shortTimeAgoSinceNow);

//输出:
//Time Ago: 4 seconds ago 
//Time Ago: 4s 

//设置好支持中文输出:
//Time Ago: 4秒钟前 
//Time Ago: 4秒

DateTools提供了多达33种语言的支持
如果想修改相对日期显示的文字,可以修改DateTools/Resources/DateTools.bundle下相应的文件
下图以简体中文为例:

修改相对日期显示文字

2.Date Components(日期组成部分)

获取日期的组成部分:

NSDate *date = [NSDate date];
NSInteger year = date.year;
NSInteger month = date.month;
NSInteger day = date.day;
NSInteger hour = date.hour;
NSInteger minute = date.minute;
NSInteger second = date.second;
    
NSLog(@"year:%ld month:%ld day:%ld hour:%ld minute:%ld second:%ld", year, month, day, hour, minute, second);
//输出: year:2016 month:5 day:23 hour:10 minute:54 second:1

DateTools默认日历为公历!!!
使用其他日历:
(如果想全局使用其他日历,修改DateTools默认日历,可以改写 NSDate+DateTools.m 中的 defaultCalendar 方法)

日历枚举
/**
  *  使用中国农历
  */
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSChineseCalendar];
    
NSDate *date = [NSDate date];
NSInteger year = [date yearWithCalendar:calendar];
NSInteger month = [date monthWithCalendar:calendar];
NSInteger day = [date dayWithCalendar:calendar];
NSInteger hour = [date hourWithCalendar:calendar];
NSInteger minute = [date minuteWithCalendar:calendar];
NSInteger second = [date secondWithCalendar:calendar];
    
NSLog(@"农历: %ld-%ld-%ld %ld:%ld:%ld", year, month, day, hour, minute, second);
NSLog(@"公历: %ld-%ld-%ld %ld:%ld:%ld", date.year, date.month, date.day, date.hour, date.minute, date.second);
//输出: 农历: 33-4-17 11:41:51
//输出: 公历: 2016-5-23 11:41:51

3.日期编辑

对日期进行编辑(年,月,日,星期,时,分,秒)
增加/减少方法:

日期编辑
/**
  *  日期增加1年
  */
NSDate *date = [NSDate date];
NSDate *newDate = [date dateByAddingYears:1];
 
NSLog(@"year:%ld newYear:%ld", date.year, newDate.year);
//输出: year:2016 newYear:2017

4.日期比较

比较两个日期大小返回一个布尔值:

日期比较

更多日期比较方法:
(很容易的得到两个日期相差的年,月,星期,日,时,分,秒)

更多日期比较方法

5.格式化日期字符串

formattedDateWithStyle:(系统格式)
formattedDateWithFormat:(自定义格式)

格式化日期字符串
/**
  *  formattedDateWithStyle(系统格式)
  */
NSDate *date = [NSDate date];
NSString *dateStringNo = [date formattedDateWithStyle:NSDateFormatterNoStyle];
NSString *dateStringShort = [date formattedDateWithStyle:NSDateFormatterShortStyle];
NSString *dateStringMedium = [date formattedDateWithStyle:NSDateFormatterMediumStyle];
NSString *dateStringLong = [date formattedDateWithStyle:NSDateFormatterLongStyle];
NSString *dateStringFull = [date formattedDateWithStyle:NSDateFormatterFullStyle];
    
NSLog(@"No: %@", dateStringNo);               //输出:   No:
NSLog(@"Short: %@", dateStringShort);         //输出:   Short: 16/5/23
NSLog(@"Medium: %@", dateStringMedium);       //输出:   Medium: 2016年5月23日
NSLog(@"Long: %@", dateStringLong);           //输出:   Long: 2016年5月23日
NSLog(@"Full: %@", dateStringFull);           //输出:   Full: 2016年5月23日 星期一
    
/**
  *  formattedDateWithFormat(自定义格式)
  */
NSString *dateStringCustom1 = [date formattedDateWithFormat:@"yyyy-MM-dd"];
NSString *dateStringCustom2 = [date formattedDateWithFormat:@"yyyy年MM月dd日"];
NSString *dateStringCustom3 = [date formattedDateWithFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *dateStringCustom4 = [date formattedDateWithFormat:@"yyyy年MM月dd日 HH:mm:ss"];
NSString *dateStringCustom5 = [date formattedDateWithFormat:@"yyyy年MM月dd日 HH点mm分ss秒"];
    
NSLog(@"Custom1: %@", dateStringCustom1);       //输出:   Custom1: 2016-05-23
NSLog(@"Custom2: %@", dateStringCustom2);       //输出:   Custom2: 2016年05月23日
NSLog(@"Custom3: %@", dateStringCustom3);       //输出:   Custom3: 2016-05-23 13:42:53
NSLog(@"Custom4: %@", dateStringCustom4);       //输出:   Custom4: 2016年05月23日 13:42:53
NSLog(@"Custom5: %@", dateStringCustom5);       //输出:   Custom5: 2016年05月23日 13点42分53秒

字符 说明
yy 年的后2位
yyyy 完整年
M 1~12 月(不带0)
MM 1~12 月(带0)
MMM Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec (1~12月_简写)
MMMM January/February/March/April/May/June/July/August/September/October/November/December (1~12月_全写)
d 1~31 日(不带0)
dd 1~31 日(带0)
EEE Sun/Mon/Tue/Wed/Thu/Fri/Sat (星期_简写)
EEEE Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday (星期_全写)
aa AM/PM (上午/下午)
H 0~23 时(24小时制,不带0)
HH 0~23 时(24小时制,带0)
h 1~12 时(12小时制,不带0)
hh 1~12 时(24小时制,带0)
m 0~59 分(不带0)
mm 0~59 分(带0)
s 0~59 秒(不带0)
ss 0~59 秒(带0)
S 毫秒

Time Periods「时间段」


DateTools提供DTTimePeriod来简化时间段的操作

初始化和获取时间段信息

/**
  *  通过起始时间来初始化时间段
  */
NSDate *startDate = [NSDate date];
NSDate *endDate = [startDate dateByAddingHours:2];
DTTimePeriod *timePeriod =[[DTTimePeriod alloc] initWithStartDate:startDate endDate:endDate];
    
BOOL hasStartDate = timePeriod.hasStartDate;        //是否有开始时间
BOOL hasEndDate   = timePeriod.hasEndDate;          //是否有结束时间
BOOL isMoment     = timePeriod.isMoment;            //是否开始时间和结束时间相同
    
double  durationInYears   = [timePeriod durationInYears];    //相差年
double  durationInWeeks   = [timePeriod durationInWeeks];    //相差周
double  durationInDays    = [timePeriod durationInDays];     //相差日
double  durationInHours   = [timePeriod durationInHours];    //相差小时
double  durationInMinutes = [timePeriod durationInMinutes];  //相差分
double  durationInSeconds = [timePeriod durationInSeconds];  //相差秒
    
NSLog(@"%f年 %f周 %f日 %f小时 %f分 %f秒",durationInYears, durationInWeeks, durationInDays, durationInHours, durationInMinutes, durationInSeconds);
//输出: 0.000000年 0.000000周 0.000000日 2.000000小时 120.000000分 7200.000000秒

更多初始化时间段方法:

更多初始化时间段方法

时间段操作

移动时间段:
shiftEarlierWithSize 时间段整体前移

shiftLaterWithSize 时间段整体后移

/**
  *  移动时间段
  */
NSDate *startDate = [NSDate date];
NSDate *endDate = [startDate dateByAddingDays:2];
DTTimePeriod *timePeriod =[[DTTimePeriod alloc] initWithStartDate:startDate endDate:endDate];
    
NSLog(@"开始:%@", [timePeriod.StartDate formattedDateWithStyle:NSDateFormatterMediumStyle]);
NSLog(@"结束:%@", [timePeriod.EndDate formattedDateWithStyle:NSDateFormatterMediumStyle]);
//输出: 开始:2016年5月23日
//输出: 结束:2016年5月25日
    
[timePeriod shiftEarlierWithSize:DTTimePeriodSizeDay];              //提前1天
    
NSLog(@"开始:%@", [timePeriod.StartDate formattedDateWithStyle:NSDateFormatterMediumStyle]);
NSLog(@"结束:%@", [timePeriod.EndDate formattedDateWithStyle:NSDateFormatterMediumStyle]);
//输出: 开始:2016年5月22日
//输出: 结束:2016年5月24日

[timePeriod shiftLaterWithSize:DTTimePeriodSizeDay amount:2];       //延后2天
    
NSLog(@"开始:%@", [timePeriod.StartDate formattedDateWithStyle:NSDateFormatterMediumStyle]);
NSLog(@"结束:%@", [timePeriod.EndDate formattedDateWithStyle:NSDateFormatterMediumStyle]);
//输出: 开始:2016年5月24日
//输出: 结束:2016年5月26日

延长/缩短时间段:
shortenWithAnchorDate 延长(开始时间/中间时间/结束时间)
lengthenWithAnchorDate 缩短(开始时间/中间时间/结束时间)

/**
  *  时间段延长/缩短
  */
NSDate *startDate = [NSDate date];
NSDate *endDate = [startDate dateByAddingDays:2];
DTTimePeriod *timePeriod =[[DTTimePeriod alloc] initWithStartDate:startDate endDate:endDate];
    
NSLog(@"时长: %.2f天", [timePeriod durationInDays]);
//输出: 时长: 2.00天

[timePeriod lengthenWithAnchorDate:DTTimePeriodAnchorEnd size:DTTimePeriodSizeDay amount:1];        //延长1天(增加结束时间)

NSLog(@"时长: %.2f天", [timePeriod durationInDays]);
//输出: 时长: 3.00天

[timePeriod shortenWithAnchorDate:DTTimePeriodAnchorStart size:DTTimePeriodSizeDay amount:4];       //缩短4天(减少开始时间)
    
NSLog(@"时长: %.2f天", [timePeriod durationInDays]);
//输出: 时长: 0.00天

时间段关系

两个时间段关系相关方法:

时间段关系方法

两个时间段关系所有可能性:

时间段关系可能性

时间段关系枚举DTTimePeriodRelation:

/**
  *  DTTimePeriodRelation时间段关系枚举
  */
typedef NS_ENUM(NSUInteger, DTTimePeriodRelation){
    DTTimePeriodRelationAfter,      
    DTTimePeriodRelationStartTouching,    
    DTTimePeriodRelationStartInside,
    DTTimePeriodRelationInsideStartTouching,
    DTTimePeriodRelationEnclosingStartTouching,
    DTTimePeriodRelationEnclosing,
    DTTimePeriodRelationEnclosingEndTouching,
    DTTimePeriodRelationExactMatch,
    DTTimePeriodRelationInside,
    DTTimePeriodRelationInsideEndTouching,
    DTTimePeriodRelationEndInside,
    DTTimePeriodRelationEndTouching,
    DTTimePeriodRelationBefore,
    DTTimePeriodRelationNone      
};

Time Period Groups「时间段组」


DateTools提供两种时间段组类:
DTTimePeriodCollection 时间段集合 (允许存储彼此有交集的时间段)
DTTimePeriodChain 时间段链接 (不允许存储彼此有交集的时间段)

DTTimePeriodCollection和DTTimePeriodChain就像NSArray一样,你可以像操作数组一样对它们中的DTTimePeriod对象进行添加,插入,删除,不同之处在于如何处理时间段

DTTimePeriodCollection (时间段集合)

一个规则相对宽松的时间段集合
默认是无序的,但是支持通过调用方法排序
有自己的属性,例如StartDate和EndDate属性是根据内部时间段推测出来的
允许存储有重叠的时间段

时间段集合
//时间段集合
DTTimePeriodCollection *timePeriodCollection = [DTTimePeriodCollection collection]; 
/**
  *  时间段
  *
  *  当前时间为: 2016年5月24日 
  */
DTTimePeriod *timePeriod1 = [DTTimePeriod timePeriodWithSize:DTTimePeriodSizeDay startingAt:[NSDate date]];
DTTimePeriod *timePeriod2 = [DTTimePeriod timePeriodWithSize:DTTimePeriodSizeDay endingAt:[NSDate date]];
    
NSLog(@"开始:%@ 结束:%@", [timePeriod1.StartDate formattedDateWithStyle:NSDateFormatterMediumStyle], [timePeriod1.EndDate formattedDateWithStyle:NSDateFormatterMediumStyle]);
NSLog(@"开始:%@ 结束:%@", [timePeriod2.StartDate formattedDateWithStyle:NSDateFormatterMediumStyle], [timePeriod2.EndDate formattedDateWithStyle:NSDateFormatterMediumStyle]);
//输出:   开始:2016年5月24日 结束:2016年5月25日
//输出:   开始:2016年5月23日 结束:2016年5月24日
    
/**
 *  时间段集合操作
 */
//添加
[timePeriodCollection addTimePeriod:timePeriod1];
//插入
[timePeriodCollection insertTimePeriod:timePeriod2 atIndex:0];
//移除
[timePeriodCollection removeTimePeriodAtIndex:0];
    
/**
 *  时间段集合排序
 */
//按开始时间升序
[timePeriodCollection sortByStartAscending];
//按开始时间降序
[timePeriodCollection sortByStartDescending];
//按结束时间升序
[timePeriodCollection sortByEndAscending];
//按结束时间降序
[timePeriodCollection sortByEndDescending];
//按持续时间升序
[timePeriodCollection sortByDurationAscending];
//按持续时间降序
[timePeriodCollection sortByDurationDescending];
    
//从时间段集合中获取时间段
DTTimePeriod *firstTimePeriod = [timePeriodCollection objectAtIndexedSubscript:0];
时间段集合操作示意图

获取一个NSDate对象或一个DTTimePeriod对象与一个时间段集合的相对关系

时间段集合操作方法

DTTimePeriodChain (时间链)

一个紧密耦合的时间段集合
通常依据开始时间和结束时间存储时间段对象
有自己的属性,例如StartDate和EndDate属性是根据内部时间段推测出来的
不允许存储有重叠的时间段

时间链
    
//创建时间链
DTTimePeriodChain *chain = [DTTimePeriodChain chain];
    
//创建时间段
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat: @"YYYY MM dd HH:mm:ss.SSS"];
    
DTTimePeriod *firstPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2014 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"]];
DTTimePeriod *secondPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2016 11 05 18:15:12.000"]];
    
//添加
[chain addTimePeriod:firstPeriod];
[chain addTimePeriod:secondPeriod];
//插入
[chain insertTimePeriod:firstPeriod atInedx:0];
//移除
[chain removeTimePeriodAtIndex:0];
//移除最晚时间段
[chain removeLatestTimePeriod];
//移除最早时间段
[chain removeEarliestTimePeriod];
    
//获取集合中的元素.
firstPeriod = chain[0];

新加入的时间段,时长不变,起始时间变为前一个时间段的结束时间,结束时间对应前移后后移.在非零位置新插入的时间,其后的时间段相应后移.在零位置插入的时间,集合的起始时间前移

时间链操作示意图

相关文章

网友评论

  • Qson1:已知历时的总秒数 如何获取年月日,和昨天 今天 明天 这种
  • iCodingBoy:很好
  • xxttw:感谢分享
  • 齐刘海姑娘:哈喽~您的文章已收录专题【我不是程序猿,请叫我攻城狮】http://www.jianshu.com/collection/db91065b98c6,欢迎关注投稿哦~ :kissing_heart: :heart: :heart: :smile:
  • ff6250868c5d:你好,如果我从服务器获得一个时间年月日,我怎么可以在后面加星期几呢?望指教。
    LuisX:@sandouchan
    你可以这样:
    NSString *dateString = @"05/31/2016 19:30";
    NSDate *date = [NSDate dateWithString:dateString formatString:@"MM/dd/yyyy HH:mm"];
    NSString *resultStr = [date formattedDateWithFormat:@"yyyy-MM-dd EEE"];
    NSLog(@"%@", resultStr);
    //输出: 2016-05-31 周二
    ff6250868c5d:@LuisX 但是我后台返回的数据是 string = 05/31/2016 19:30,我想转成2016-05-31 周一,这样的~不知怎么转~
    LuisX:@sandouchan 你看一下5格式化字符串,使用系统的fullStyle打印,或者使用自定义打印,在格式上添加日期格式,表中已经包含
  • lxyz22zp:的确全面
  • ivylee_mr:非常适用
  • 37db59ebcd21:根据 年 月份 第几周 能取到具体日期的吗
    LuisX:@就这么漂来飘去 这个数组中包含的是根据所传的年,月,星期,返回的开始时间到结束时间,你可以取数组中的第一个元素。既某年某月的第某周的开始日期
    37db59ebcd21:@LuisX 谢谢解决了我的问题 但是还是有点问题 我需要是这样的需求 传 年 , 月和这个月的第几周 然后得到是这周的开始时间 比如我传的是2016 5 4 得到是 2016-05-23 这样的 改怎样改一下呢
    - (NSString *)getDateWithYear:(NSInteger )year Month:(NSInteger)month Week:(NSInteger)week{
    NSMutableArray *resultDateArr = [NSMutableArray array];
    NSDate * date = [NSDate dateWithYear:year month:month day:1];
    for (NSInteger i = 0; i < date.daysInMonth; i++) {
    if (week == date.weekOfMonth) {
    //NSLog(@"%@", [date formattedDateWithStyle:NSDateFormatterMediumStyle]);
    [resultDateArr addObject:date];
    }
    date = [date dateByAddingDays:1];
    }

    NSString *str = [[NSString stringWithFormat:@"%@",resultDateArr[2]] substringWithRange:NSMakeRange(0, 10)];

    return str;
    }

    这个是打印的
    <__NSArrayM 0x7fc819cdabf0>(
    2016-05-21 16:00:00 +0000,
    2016-05-22 16:00:00 +0000,
    2016-05-23 16:00:00 +0000,
    2016-05-24 16:00:00 +0000,
    2016-05-25 16:00:00 +0000,
    2016-05-26 16:00:00 +0000,
    2016-05-27 16:00:00 +0000
    )


    LuisX:@就这么漂来飘去 可以的我帮你写以一段,你看看
    - (NSArray *)getDateWithYear:(NSInteger )year Month:(NSInteger)month Week:(NSInteger)week{
    NSMutableArray *resultDateArr = [NSMutableArray array];
    NSDate * date = [NSDate dateWithYear:year month:month day:1];

    for (NSInteger i = 0; i < date.daysInMonth; i++) {
    if (week == date.weekOfMonth) {
    //NSLog(@"%@", [date formattedDateWithStyle:NSDateFormatterMediumStyle]);
    [resultDateArr addObject:date];
    }
    date = [date dateByAddingDays:1];
    }

    return resultDateArr;
    }
  • Evan_W:感谢大神,:pray:,么么哒:kissing_heart:

本文标题:DateTools使用「日期工具库」

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