代码改变世界

【iOS】得到当前年、月、周的第一天和最后一天

2015-03-25 11:04  l4y  阅读(5713)  评论(0编辑  收藏  举报

在写一个记账软件,其中有个统计功能。比如,统计某月的支出,需要知道某天所在的月的第一天和最后一天,以便从数据库中根据时间取数据。

话不多说,上代码:

//
//  EBDate.h
//  ChargeMoney
//
//  Created by eagle on 15-3-24.
//  Copyright (c) 2015年 EagleB. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface EBDate : NSObject
/**
 *  得到这个周的第一天和最后一天
 */
+(NSArray *)getFirstAndLastDayOfThisWeek;
/**
 *  得到这个月的第一天和最后一天
 */
+(NSArray *)getFirstAndLastDayOfThisMonth;
/**
 *  得到今年的第一天和最后一天
 */
+(NSArray *)getFirstAndLastDayOfThisYear;
@end
//
//  EBDate.m
//  ChargeMoney
//
//  Created by eagle on 15-3-24.
//  Copyright (c) 2015年 EagleB. All rights reserved.
//

#import "EBDate.h"

@implementation EBDate

+(NSArray *)getFirstAndLastDayOfThisWeek
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *dateComponents = [calendar components:NSWeekdayCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
    NSInteger weekday = [dateComponents weekday];   //第几天(从sunday开始)
    NSInteger firstDiff,lastDiff;
    if (weekday == 1) {
        firstDiff = -6;
        lastDiff = 0;
    }else {
        firstDiff =  - weekday + 2;
        lastDiff = 8 - weekday;
    }
    NSInteger day = [dateComponents day];
    NSDateComponents *firstComponents = [calendar components:NSWeekdayCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
    [firstComponents setDay:day+firstDiff];
    NSDate *firstDay = [calendar dateFromComponents:firstComponents];
    
    NSDateComponents *lastComponents = [calendar components:NSWeekdayCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
    [lastComponents setDay:day+lastDiff];
    NSDate *lastDay = [calendar dateFromComponents:lastComponents];
    return [NSArray arrayWithObjects:firstDay,lastDay, nil];
}

+(NSArray *)getFirstAndLastDayOfThisMonth
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDate *firstDay;
    [calendar rangeOfUnit:NSMonthCalendarUnit startDate:&firstDay interval:nil forDate:[NSDate date]];
    NSDateComponents *lastDateComponents = [calendar components:NSMonthCalendarUnit | NSYearCalendarUnit |NSDayCalendarUnit fromDate:firstDay];
    NSUInteger dayNumberOfMonth = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]].length;
    NSInteger day = [lastDateComponents day];
    [lastDateComponents setDay:day+dayNumberOfMonth-1];
    NSDate *lastDay = [calendar dateFromComponents:lastDateComponents];
    return [NSArray arrayWithObjects:firstDay,lastDay, nil];
}

+(NSArray *)getFirstAndLastDayOfThisYear
{
    //通过2月天数的改变,来确定全年天数
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setTimeZone:[NSTimeZone systemTimeZone]];
    [formatter setDateFormat:@"yyyy"];
    NSString *dateStr = [formatter stringFromDate:[NSDate date]];
    dateStr = [dateStr stringByAppendingString:@"-02-14"];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSDate *aDayOfFebruary = [formatter dateFromString:dateStr];
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDate *firstDay;
    [calendar rangeOfUnit:NSYearCalendarUnit startDate:&firstDay interval:nil forDate:[NSDate date]];
    NSDateComponents *lastDateComponents = [calendar components:NSMonthCalendarUnit | NSYearCalendarUnit | NSDayCalendarUnit fromDate:firstDay];
    NSUInteger dayNumberOfFebruary = [calendar rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:aDayOfFebruary].length;
    NSInteger day = [lastDateComponents day];
    [lastDateComponents setDay:day+337+dayNumberOfFebruary-1];
    NSDate *lastDay = [calendar dateFromComponents:lastDateComponents];
    
    return [NSArray arrayWithObjects:firstDay,lastDay, nil];
}

@end

注意频繁创建Canlendar,会严重消耗系统性能,该文章的方法仅提供一个参考。

感谢这篇文章:http://my.oschina.net/yongbin45/blog/156181#OSC_h4_7

 

--------------------------------------

更新:

上边的方法有点笨了,贴上最新的代码。可能过段时间看,这方法又笨了。不得不说,底层的API提供的功能越来强大,你要写的越来越简单。

 1 /**
 2  *  month: range from 1 to 12
 3  **/
 4 + (NSArray<NSDate *> *)getFirstAndLastDayOfMonth:(NSInteger)month inYear:(NSInteger)year {
 5     NSCalendar *calendar = [NSCalendar currentCalendar];
 6     NSDate *date = [self getDateWithMonth:month year:year];
 7     NSDate *firstDay;
 8     NSTimeInterval interval;
 9     [calendar rangeOfUnit:NSCalendarUnitMonth startDate:&firstDay interval:&interval forDate:date];
10     NSDateComponents *lastDateComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear |NSCalendarUnitDay fromDate:firstDay];
11     NSUInteger dayNumberOfMonth = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length;
12     NSInteger day = [lastDateComponents day];
13     [lastDateComponents setDay:day + dayNumberOfMonth];
14     lastDateComponents.nanosecond = lastDateComponents.nanosecond - 1000000;
15     NSDate *lastDay = [calendar dateFromComponents:lastDateComponents];
16     return [NSArray arrayWithObjects:firstDay,lastDay, nil];
17 }
18 
19 + (NSArray<NSDate *> *)getFirstAndLastDayOfYear:(NSInteger)year {
20     NSDate *date = [self getDateWithYear:year];
21     NSCalendar *calendar = [NSCalendar currentCalendar];
22     NSDate *firstDay;
23     [calendar rangeOfUnit:NSCalendarUnitYear startDate:&firstDay interval:nil forDate:date];
24     NSDateComponents *lastDateComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitDay fromDate:firstDay];
25     NSUInteger dayNumberOfYear = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitYear forDate:date].length;
26     NSInteger day = [lastDateComponents day];
27     [lastDateComponents setDay:day + dayNumberOfYear];
28     lastDateComponents.nanosecond = lastDateComponents.nanosecond - 1000000;
29     NSDate *lastDay = [calendar dateFromComponents:lastDateComponents];
30     return [NSArray arrayWithObjects:firstDay,lastDay, nil];
31 }
32 
33 + (NSDate *)getDateWithMonth:(NSInteger)month year:(NSInteger)year {
34     NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
35     dateComponents.year = year;
36     dateComponents.month = month;
37 
38     NSCalendar *calendar = [NSCalendar currentCalendar];
39     NSDate *date = [calendar dateFromComponents:dateComponents];
40     return date;
41 }
42 
43 + (NSDate *)getDateWithYear:(NSInteger)year {
44     NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
45     dateComponents.year = year;
46 
47     NSCalendar *calendar = [NSCalendar currentCalendar];
48     NSDate *date = [calendar dateFromComponents:dateComponents];
49     return date;
50 }
View Code