时间与日期类封装

时间:2022-10-20 22:06:07

时间日历类

导语

在iOS开发时,会经常用到一些处理时间的函数和方法,比如求当前时间,计算两个日期差几天,格式化现在时间与给定的秒数的时间差等。

所以就整理并归纳了一些比较实用的方法。

主要用到的类有: NSDate, NSDateFormatter, NSCalendar, NSDateComponents, NSTimeInterval,

一、类的实现

1. CXZTimeUtil.h

#import <UIKit/UIKit.h>

@interface CXZTimeUtil : NSObject

/** * 得到单例 *T *  @return 单例的对象 */
+ (id)getInstance;


/** * 得到当前时区的时间,一般为北京时间 * *  @return NSDate对象 */
- (NSDate *)dateNow;


/** * 获取自1970年到现在的秒数 * *  @return 秒数 */
- (NSInteger)currentSecond;


/** * 获取自1970年到现在的毫秒数 * *  @return 毫秒数 */
- (long long)currentMsec;


/** * 获取当前的日期对象 * *  @return 日期对象 */
- (NSDateComponents *)currentDateCompoent;


/** * 通过给定的NSDate得到日期对象 * *  @param date NSDate * *  @return 日期对象 */
- (NSDateComponents *)dateCompoentFromDate:(NSDate *)date;


/** * 获取某年某月最大天数 * *  @param year 年份 *  @param month 月份 * *  @return 天数 */
- (NSInteger)maxDayForYear:(NSInteger *)year month:(NSInteger)month;


/** * 通过制定的参数获取NSDate对象 * *  @param year 年 *  @param month 月 *  @param day 日 *  @param hour 时 *  @param monute 分 *  @param second 秒 * *  @return NSDate对象 */
- (NSDate *)dateFromYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second;


/** * 通过components获取NSDate对象 * *  @param components NSDateComponents类型 * *  @return NSDate对象 */
- (NSDate *)dateFromComponents:(NSDateComponents *)components;


/** * 通过秒数来获取时间字符串 * *  @param second 自1970年开始的秒数 * *  @return 时间字符串 */
- (NSString *)dateStringFromSecond:(NSInteger)second;


/** * 得到date之后或之前的日子,正表示之后,负表示之前 * *  @param date 基准时间 *  @param year 年 *  @param month 月 *  @param day 日 * *  @return 计算之后的日期 */
- (NSDate *)dateAfterFromDate:(NSDate *)date withYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;


/** * 计算两个日期差几天 * *  @param date1 日期1 *  @param date2 日期2 * *  @return 差的天数 */
- (NSInteger)differenceFromDate:(NSDate *)date1 toDate:(NSDate *)date2;


/** * 格式化现在时间与给定的秒数的时间差 * *  @param second 自1970年开始的秒数 * *  @return 格式化后的字符串 */
- (NSString *)formatDifferenceToNowFromSecond:(NSInteger)second;

@end

}

2. CXZTimerUtil.m

#import "CXZTimeUtil.h"

@implementation CXZTimeUtil

+ (id)getInstance {
    //单例模式
    static CXZTimeUtil *singleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[CXZTimeUtil alloc] init];
    });

    return singleton;
}

- (NSDate *)dateNow {
    //获取当前时区的当前时间
    NSDate *date = [NSDate date];
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    NSInteger interval = [zone secondsFromGMTForDate:date];
    NSDate *localeDate = [date dateByAddingTimeInterval:interval];
    return localeDate;
}

- (NSInteger)currentSecond {
    NSDate *now = [NSDate date];

    return [now timeIntervalSince1970];
}

- (long long)currentMsec {
    NSDate *now = [NSDate date];

    //秒数乘以1000
    return [now timeIntervalSince1970] * 1000;
}

- (NSDateComponents *)currentDateCompoent {
    NSDate *now = [NSDate date];

    return [self dateCompoentFromDate:now];
}

- (NSDateComponents *)dateCompoentFromDate:(NSDate *)date {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    return [calendar components:unitFlags fromDate:date];
}

- (NSInteger)maxDayForYear:(NSInteger *)year month:(NSInteger)month {
    NSString *date = [NSString stringWithFormat:@"%04ld-%02ld-01", (long)year, month];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSDate *today = [formatter dateFromString:date];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSRange days = [calendar rangeOfUnit:NSCalendarUnitDay
                                  inUnit:NSCalendarUnitMonth
                                 forDate:today];

    return days.length;
}

- (NSDate *)dateFromYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second {
    NSDateComponents* components = [[NSDateComponents alloc] init];
    [components setYear:year];
    [components setMonth:month];
    [components setDay:day];
    [components setHour:hour];
    [components setMinute:minute];
    [components setSecond:second];
    NSCalendar* calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    return [calendar dateFromComponents:components];
}

- (NSDate *)dateFromComponents:(NSDateComponents *)components {
    NSCalendar* calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    return [calendar dateFromComponents:components];
}


- (NSString *)dateStringFromSecond:(NSInteger)second {
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:second];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"YYYY-MM-dd HH:MM:ss"];

    return [formatter stringFromDate:date];
}


- (NSDate *)dateAfterFromDate:(NSDate *)date withYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day {
    NSDateComponents *comps = [[NSDateComponents alloc] init];
    [comps setYear:year];
    [comps setMonth:month];
    [comps setDay:day];
    NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDate *mDate = [calender dateByAddingComponents:comps toDate:date options:0];
    return mDate;
}

- (NSInteger)differenceFromDate:(NSDate *)date1 toDate:(NSDate *)date2 {
    NSTimeInterval time = [date2 timeIntervalSinceDate:date1];
    NSInteger days = time / (3600 * 24);

    return days;
}

- (NSString *)formatDifferenceToNowFromSecond:(NSInteger)second {
    NSInteger nowSecond = [self currentSecond];
    NSInteger diff = nowSecond - second;
    if (diff < 60) { //几秒前
        return [NSString stringWithFormat:@"%ld秒前", diff];
    }
    if (diff >= 60 && diff < 3600) { //几分钟前
        return [NSString stringWithFormat:@"%ld分钟前", diff/60];
    }
    if (diff >= 3600 && diff < 3600 * 24) { //几小时前
        return [NSString stringWithFormat:@"%ld小时前", diff/3600];
    }
    //几天前
    return [NSString stringWithFormat:@"%ld天前", diff/(3600*24)];
}

@end


二、部分代码解释

1. - (NSString *)formatDifferenceToNowFromSecond:(NSInteger)second;

在开发时往往会遇到后台端返回如下的json

"data": [{
    "order_id":"32",                我的订单id
    "integral":"0",                 我的订单积分
    "add_time":"1439046677",        我的订单添加时间
    "goods_id":"156",               我的订单对应的景点(或发现)的id号
    "goods_name":"啊啊啊啊"           我的订单对应的景点(或发现)的名称
    },。。。。。已经省略
}]

add_time = 1439046677,这是从本条数据生成的时间到1970年1月1日00:00:00的秒数,所以你需要用到 - (NSString *)formatDifferenceToNowFromSecond:(NSInteger)second来求出过了几秒、几分钟或者几天。

2. - (NSDate *)dateNow;

如果你用 [NSDate date]方法你将会得到GMT时间,这会和我们的北京时间相差8个小时,所以当你想要得到北京的当时时间,你就必须通过

- (NSDate *)dateNow {
    //获取当前时区的当前时间
    NSDate *date = [NSDate date];
    NSTimeZone *zone = [NSTimeZone systemTimeZone];
    NSInteger interval = [zone secondsFromGMTForDate:date];
    NSDate *localeDate = [date dateByAddingTimeInterval:interval];
    return localeDate;
}

来获取当前时区的当前时间,这是通过相差的秒数相加实现的。

3. 其他时间的操作

我另一篇博客会详细介绍时间日历的其他操作。希望各位能用上。

时间与日期处理NSDate, NSCalendar