iOS NSDate常用的方法及DateFormatter的優(yōu)化

通過[NSDate date]返回的一定是零時(shí)區(qū)的時(shí)間

    NSDate *date = [NSDate date];
    NSLog(@"date時(shí)間 = %@", date);
    //date時(shí)間 = 2018-05-31 06:43:07 +0000
    
    //如果沒有規(guī)定formatter的時(shí)區(qū),那么formatter默認(rèn)的就是當(dāng)前時(shí)區(qū),比如現(xiàn)在在北京就是東八區(qū),在東京就是東九區(qū)
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    //最結(jié)尾的Z表示的是時(shí)區(qū),零時(shí)區(qū)表示+0000,東八區(qū)表示+0800
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
   // 使用formatter轉(zhuǎn)換后的date字符串變成了當(dāng)前時(shí)區(qū)的時(shí)間
    NSString *dateStr = [formatter stringFromDate:date];
    NSLog(@"字符串時(shí)間 = %@", dateStr);
    //字符串時(shí)間 = 2018-05-31 14:43:07 +080

上面例子中NSDate時(shí)間轉(zhuǎn)字符串時(shí)間時(shí),NSDateFormatter并沒有設(shè)置時(shí)區(qū),而是使用當(dāng)前地區(qū)的時(shí)區(qū),這和設(shè)置系統(tǒng)系統(tǒng)時(shí)區(qū)
formatter.timeZone = [NSTimeZone systemTimeZone] 的效果是一樣的。

轉(zhuǎn)字符串時(shí)間的時(shí)區(qū)設(shè)置

   //我們也可以規(guī)定一定使用某一個(gè)時(shí)區(qū):
   NSDate *date = [NSDate date];
   NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
   [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
   formatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];//東八區(qū)時(shí)間
   //這樣不管我們的手機(jī)是在哪里,打印出來的時(shí)間都是東八區(qū)的時(shí)間
   
   formatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Tokyo"];//東九區(qū)時(shí)間
   formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];//零區(qū)時(shí)間
   formatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];//零區(qū)時(shí)間,和GMT一樣
   NSString *dateStr = [formatter stringFromDate:date];
   NSLog(@"字符串時(shí)間 = %@", dateStr);

凡是返回結(jié)果為NSDate類型的,得到的時(shí)間都是零時(shí)區(qū)

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
    NSDate *newDate = [formatter dateFromString:@"2016-12-07 14:06:24 +0800"];
    NSLog(@"newDate = %@", newDate);
    //newDate = 2016-12-07 06:06:24 +0000
//我們看到這樣轉(zhuǎn)化后就出現(xiàn)了問題轉(zhuǎn)后之后得到的時(shí)間的時(shí)區(qū)又變成了零時(shí)區(qū)。問題就出在,凡是返回結(jié)果為NSDate類型的,得到的時(shí)間都是零時(shí)區(qū),都是零時(shí)區(qū)!都是零時(shí)區(qū)!

//閏年2月份是29天

- (NSArray *)getAllWeekDate {//獲取今年所有的周
    
    NSDate *nowDate = [NSDate date];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *comp = [calendar components: NSCalendarUnitWeekday | NSCalendarUnitWeekOfYear fromDate:nowDate];
    // 獲取今天是周幾 (周一是2,周日是1)
    NSInteger weekDay = [comp weekday];
    //這周是今年的第幾周(注意:第一周編號(hào)為1不為0)
    NSInteger weekOfYear = [comp weekOfYear];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyyMMdd"];
    NSDate *date = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]];
    //這周的開始和結(jié)束時(shí)間 (注意:+1 -1 避開臨界值)
    NSDate *startdate = [date dateByAddingTimeInterval:24*3600*(2 - weekDay)+1];
    NSDate *enddate = [date dateByAddingTimeInterval:24*3600*(9 - weekDay)-1];
    NSMutableArray *dateArray = [[[NSMutableArray alloc] init] mutableCopy];
    //一年52周  獲取一年的所有周一和周日的日期(注意:第一周編號(hào)為1不為0)
    for (int i = 1; i <= 52; i++) {
        NSDate *startdate1 = [startdate dateByAddingTimeInterval:24*3600*7*(i-weekOfYear)];
        NSDate *enddate1 = [enddate dateByAddingTimeInterval:24*3600*7*(i-weekOfYear)];
        [dateArray addObject:@[startdate1,enddate1]];
    }
    
    return dateArray;
}

指定日期是年的第幾周 月的第幾周 星期幾

    NSDate *showDate = [NSDate date];
    NSCalendar*calendar = [NSCalendar currentCalendar];
    NSDateComponents *comps =[calendar components:(NSCalendarUnitWeekOfYear | NSCalendarUnitWeekday |NSCalendarUnitWeekdayOrdinal) fromDate:showDate];
    NSInteger week = [comps weekOfYear]; // 今年的第幾周
    NSInteger weekday = [comps weekday]; // 星期幾(注意,周日是“1”,周一是“2”。。。。)
    NSInteger weekdayOrdinal = [comps weekdayOrdinal]; // 這個(gè)月的第幾周

當(dāng)前日期所在周的周一 和 周日

/**
 獲取指定日期的周一 和 周末的日期

 @param date 某一日期
 @return @“10.13-10.19”
 */
+ (NSString *)weekTimeForDate:(NSDate *)date {
    
    NSDate *nowDate = date;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *comp = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday  fromDate:nowDate];
    // 獲取今天是周幾
    NSInteger weekDay = [comp weekday];
    // 獲取幾天是幾號(hào)
    NSInteger day = [comp day];
    NSLog(@"周幾 %ld---- 幾號(hào) %ld",(long)weekDay,(long)day);
    
    // 計(jì)算當(dāng)前日期和本周的星期一和星期天相差天數(shù)
    long firstDiff,lastDiff;
    //    weekDay = 1; weekDay == 1 == 周日
    if (weekDay == 1) {
        firstDiff = -6;
        lastDiff = 0;
    }
    else {
        firstDiff = [calendar firstWeekday] - weekDay + 1;
        lastDiff = 8 - weekDay;
    }
    NSLog(@"firstDiff: %ld   lastDiff: %ld",firstDiff,lastDiff);
    
    // 在當(dāng)前日期(去掉時(shí)分秒)基礎(chǔ)上加上差的天數(shù)
    NSDateComponents *baseDayComp = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay  fromDate:nowDate];
    
    //獲取周一日期
    [baseDayComp setDay:day + firstDiff];
    NSDate *firstDayOfWeek = [calendar dateFromComponents:baseDayComp];
    
    //獲取周末日期
    [baseDayComp setDay:day + lastDiff];
    NSDate *lastDayOfWeek = [calendar dateFromComponents:baseDayComp];
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//    [formatter setDateFormat:@"YYYY年MM月dd日"];
    [formatter setDateFormat:@"MM.dd"];
    NSString *firstDay = [formatter stringFromDate:firstDayOfWeek];
    NSString *lastDay = [formatter stringFromDate:lastDayOfWeek];
    NSLog(@"%@=======%@",firstDay,lastDay);
    NSString *dateStr = [NSString stringWithFormat:@"%@-%@",firstDay,lastDay];
    
    return dateStr;
}

NSDate與字符串互相轉(zhuǎn)換


NSDate --> NSString
//獲取當(dāng)前時(shí)間
NSDate *date = [NSDate date];
//設(shè)置日期格式
NSDateFormatter* formatter1 = [[NSDateFormatter alloc] init];
[formatter1 setDateFormat:@"yyyyMMddHHmmss"];
//變?yōu)閿?shù)字
NSString* str = [formatter1 stringFromDate:date];

NSString --> NSDate
//時(shí)間字符串
NSString *str = @"20150806070733";
//規(guī)定時(shí)間格式
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyyMMddHHmmss"];
//設(shè)置時(shí)區(qū)  全球標(biāo)準(zhǔn)時(shí)間CUT 必須設(shè)置 我們要設(shè)置中國的時(shí)區(qū)
NSTimeZone *zone = [[NSTimeZone alloc] initWithName:@“CUT"];
[formatter setTimeZone:zone];
//變回日期格式
NSDate *stringDate = [formatter dateFromString:str];
NSLog(@"stringDate = %@",stringDate);

比較兩個(gè)日期的大小

https://blog.csdn.net/hong1595/article/details/44975375

日期格式請(qǐng)傳入:2013-08-05 12:12:12;如果修改日期格式,比如:2013-08-05,則將[df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];修改為[dateformater setDateFormat:@"yyyy-MM-dd"];
/**
 比較兩個(gè)日期的大小 0 相等; 1 后者大于前者; -1 前者大于后者
 
 @param aDate 日期A
 @param bDate 日期B
 @return 0 相等; 1 B > A; -1 A > B
 */
+ (NSInteger)compareWithADate:(NSString*)aDate bDate:(NSString*)bDate {
    
    NSInteger value = 0;
    NSDateFormatter *dateformater = [[NSDateFormatter alloc] init];
    [dateformater setDateFormat:@"yyyy-MM-dd"];
    NSDate *dta = [[NSDate alloc] init];
    NSDate *dtb = [[NSDate alloc] init];
    
    dta = [dateformater dateFromString:aDate];
    dtb = [dateformater dateFromString:bDate];
    NSComparisonResult result = [dta compare:dtb];
    if (result == NSOrderedSame) {
        //        相等  aa=0
    }
    else if (result == NSOrderedAscending) {
        //bDate比aDate大
        value = 1;
    }
    else if (result == NSOrderedDescending) {
        //bDate比aDate小
        value = -1;
    }
    
    return value;
}

判斷日期是星期幾

- (NSString *)weekdayStringWithDate:(NSDate *)date {
    //獲取星期幾
    NSDateComponents *componets = [[NSCalendar autoupdatingCurrentCalendar] components:NSCalendarUnitWeekday fromDate:date];
    NSInteger weekday = [componets weekday];//1代表星期日,2代表星期一,后面依次
    NSArray *weekArray = @[@"星期日",@"星期一",@"星期二",@"星期三",@"星期四",@"星期五",@"星期六"];
    NSString *weekStr = weekArray[weekday-1];
    return weekStr;
}

判斷日期與今天是否在同一周

http://www.itdecent.cn/p/9236d6cb9d09

NSCalendar自帶方法判斷日期是否是今天

+ (NSString *)checkTheDate:(NSString *)string{

NSDateFormatter *format = [[NSDateFormatter alloc]init];
[format setDateFormat:@"yyyy-MM-dd"];
NSDate *date = [format dateFromString:string];
BOOL isToday = [[NSCalendar currentCalendar] isDateInToday:date];
NSString *strDiff = nil;

if(isToday) {
    strDiff= [NSString stringWithFormat:@"今天"];
}
return strDiff;
}

獲取當(dāng)前時(shí)間若干年、月、日之后的時(shí)間

+ (NSDate *)dateWithFromDate:(NSDate *)date years:(NSInteger)years months:(NSInteger)months days:(NSInteger)days{
    NSDate  * latterDate;
    if (date) {
        latterDate = date;
    }else{
        latterDate = [NSDate date];
    }
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute
                                          fromDate:latterDate];

    [comps setYear:years];
    [comps setMonth:months];
    [comps setDay:days];

    return [calendar dateByAddingComponents:comps toDate:latterDate options:0];
}

兩個(gè)日期之間的相差的天數(shù)

/**
 * @method
 *
 * @brief 獲取兩個(gè)日期之間的天數(shù)
 * @param fromDate       起始日期
 * @param toDate         終止日期
 * @return    總天數(shù)
 */
+ (NSInteger)numberOfDaysWithFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

    NSDateComponents    * comp = [calendar components:NSCalendarUnitDay
                                             fromDate:fromDate
                                               toDate:toDate
                                              options:NSCalendarWrapComponents];
    NSLog(@" -- >>  comp : %@  << --",comp);
    return comp.day;
}

NSDateFormatter的優(yōu)化

NSDateFormatter是線程安全的,因此我們無需擔(dān)心日期格式化對(duì)象在使用過程中被另外一條線程給修改

static NSDateFormatter *cachedDateFormatter = nil;

+ (NSDateFormatter *)cachedDateFormatter {

if (!dateFormatter) {
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[NSLocale currentLocale]];
[dateFormatter setDateFormat: @"YYYY-MM-dd HH:mm:ss"];
}

return dateFormatter;
}

//使用
NSString* str = [cachedDateFormatter stringFromDate:date];

無法分析出具體是哪一步驟是主要耗時(shí)的,但是在項(xiàng)目中,如果使用單例來對(duì)創(chuàng)建,設(shè)置日期格式這兩個(gè)步驟來緩存,使用Instrument進(jìn)行分析時(shí)確實(shí)可以將運(yùn)行時(shí)間降為不緩存時(shí)的10%左右

  • 使用C語言的api來進(jìn)行時(shí)間轉(zhuǎn)換
size_t   strftime_l(char * __restrict, size_t, const char * __restrict,
        const struct tm * __restrict, locale_t)
        __DARWIN_ALIAS(strftime_l) __strftimelike(3);
//使用C語言來做日期處理
-(void)testDateFormatterInC:(NSInteger)times {
    NSString *string = @"";
    NSDate *date;
    time_t timeInterval;
    char buffer[80];
    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
    for (int i=0; i<times; i++) {
        date = [NSDate dateWithTimeIntervalSince1970:(1545308405 + i)];
        timeInterval = [date timeIntervalSince1970];
        strftime(buffer, sizeof(buffer), "%Y年%m月%d日%H時(shí)%M分%S秒", localtime(&timeInterval));
        string = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
    }
    CFAbsoluteTime duration = (CFAbsoluteTimeGetCurrent() - startTime) * 1000.0;
    NSLog(@"==%@", string);
    NSLog(@"\n使用C語言的方案:\n計(jì)算%ld次\n耗時(shí)%f ms\n", (long)times, duration);
}

對(duì)于iOS開發(fā)的同學(xué)來說比較陌生的就是
strftime_l(buffer, sizeof(buffer), "%Y年%m月%d日%H時(shí)%M分%S秒", localtime(&timeInterval), NULL);
這這行代碼的調(diào)用,strftime_l函數(shù)接受四個(gè)參數(shù),

  1. 第一個(gè)參數(shù)buffer是C語言中字符數(shù)組用于存儲(chǔ)日期格式化后的字符串,
  2. 第二個(gè)參數(shù)是寫入buffer數(shù)組的最大值,如果格式化的字符串大于這個(gè)值,那么只會(huì)取字符串的的一部分,
  3. 第三個(gè)參數(shù)"%Y年%m月%d日%H時(shí)%M分%S秒"是日期格式,
  4. 第四個(gè)參數(shù)localtime(&timeInterval)是指向使用當(dāng)?shù)貢r(shí)區(qū)對(duì)時(shí)間戳處理得到tm類型結(jié)構(gòu)體的指針

iOS中對(duì)時(shí)間的理解

NSDateFormatterd優(yōu)化-1
NSDateFormatterd優(yōu)化-2

日歷代碼參考
http://code.cocoachina.com/view/136634

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 作者:gabriel theodoropoulos,原文鏈接,原文日期:2015-10-18譯者:ray16897...
    梁杰_numbbbbb閱讀 3,997評(píng)論 0 11
  • iOS開發(fā)中,經(jīng)常會(huì)遇到各種各樣的時(shí)間問題,8小時(shí)時(shí)差,時(shí)間戳,求時(shí)間間隔,農(nóng)歷等等。解決辦法網(wǎng)上比比皆是,但大多...
    小李龍彪閱讀 6,742評(píng)論 1 6
  • 日期/時(shí)間在開發(fā)中經(jīng)常使用, 但涉及到的無非是時(shí)間轉(zhuǎn)字符串顯示出來, 或者根據(jù)字符串獲取時(shí)間對(duì)象, 其他的涉及很少...
    流火緋瞳閱讀 23,979評(píng)論 14 31
  • 清晨,陽光明媚。七點(diǎn)多鐘的鳥兒正唱得歡快,斑駁的樹影如詩寫意,在微風(fēng)地?fù)u曳下,鋪滿小區(qū)的湖畔、樹叢。 一只雪白的大...
    豆泥兒閱讀 1,079評(píng)論 0 0
  • 若 若這三月的輕風(fēng) 能吹散四月的細(xì)雨 若這北國的霜雪 能帶走江南的楊花 若這人生只是等待 余生只剩徘徊 不知你可曾...
    筆描相思閱讀 445評(píng)論 3 4

友情鏈接更多精彩內(nèi)容