给定NSDate,找到上个月的第四天

时间:2015-02-24 21:01:48

标签: objective-c nsdate nscalendar nsdatecomponents

我正在尝试根据当前日期计算NSDate对象。如果当前日期是2015年4月1日,我需要生成2014年12月31日的日期。如果当前日期是2015年4月30日,我仍然需要生成日期,2014年12月31日。但是,如果是2015年5月1日,我需要在2015年1月31日生成。换句话说,无论我在哪个月,我都需要从四个月前开始的月末日期,无论我在当月的哪个月。

我到目前为止的代码是:

    NSCalendar *theCalendar = [NSCalendar currentCalendar];
    NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
    [dayComponent setDay:-90];
    NSDate *nextDate = [theCalendar dateByAddingComponents:dayComponent toDate:[NSDate date] options:0];

    NSLog(@"The date I am getting is: %@", nextDate);

上面的代码给出了当前日期前90天的日期值,但我需要的日期始终是4个月前的月末。

2 个答案:

答案 0 :(得分:2)

正如您已经发现的那样,您需要一个开始日期和日历:

NSDate *startingDate = [NSDate date];
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];

您需要当前日期的组件,但只需要当前月份,因为您不关心当月的特定日期:

NSDateComponents *components = [calendar
    components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth
    fromDate:startingDate];

你说你想要上个月的第四天。由于月份的天数不同,因此最后一天会因月份而异。但是所有月份都有第一天,而且那些头几天总是编号为1.所以最简单的方法是首先回溯三个月来计算“上个月第四天的最后一天”:

components.month -= 3;

然后,在那个月前一天去:

components.day = -1;

最后,您需要清楚地了解NSDate代表即时的时间,但是一天(如“2015年4月1日”)是时间间隔,在特定时刻开始和结束。如果您要使用NSDate代表一整天,那么您将在该时间间隔内存储一个瞬间。你想要存储第一个或最后一个瞬间(两个都是中午); that causes problems for some days in some time zones。相反,使用正午作为你的瞬间:

components.hour = 12;

现在,您已准备好向日历询问新的NSDate

NSDate *lastDayOfFourthPriorMonth = [calendar dateFromComponents:components];

答案 1 :(得分:1)

您希望熟悉NSCalendarNSDateComponents。如果您阅读这两个API文档,您将能够汇总答案。

从概念上讲,您希望使用NSCalendar components:fromDate:来获取当前日期的组件(日,月,年)。

然后,您将在4个月后将该月值计算出去。现在,如果这包裹在1月份以后,你知道你需要确定多少,以便你调整并保持在几个月内[1..12]。此外,您还需要在此时减少年份。

知道这个月,你可以通过几种方式找到那个月的最后一天;其中最粗略的是保持自己的枚举...但是使用NSCalendar可能会有更好的方式,这也是闰年2月的原因。

最后,您可以使用NSCalendar方法dateFromComponents:从您汇编的组件构建结果日期。

请参阅@rob mayoff的优秀答案,这是对这一理论和IMO更具体的实现,正确答案。