Iphone NSDate-一年前,困境

Iphone NSDate-一年前,困境,iphone,objective-c,ios,nsdate,nscalendar,Iphone,Objective C,Ios,Nsdate,Nscalendar,我正在尝试做一些对我来说有点困难的事情。但我相信有人有一些见解 给定一个日期,比如说2011年1月17日,我试图找出一年前这个日期对应的日期。所以2011年1月17日是星期一,一年前,这一天是2010年1月18日(也是星期一)。事实证明,2010年1月18日是2011年1月17日之前354天。我原本以为只需将非闰年减去365天,闰年减去366天,但如果在本例中这样做,您将得到2010年1月17日,也就是周日,而不是周一 因此,在带有NSDate和NSCalendar的Objective-C中,我

我正在尝试做一些对我来说有点困难的事情。但我相信有人有一些见解

给定一个日期,比如说2011年1月17日,我试图找出一年前这个日期对应的日期。所以2011年1月17日是星期一,一年前,这一天是2010年1月18日(也是星期一)。事实证明,2010年1月18日是2011年1月17日之前354天。我原本以为只需将非闰年减去365天,闰年减去366天,但如果在本例中这样做,您将得到2010年1月17日,也就是周日,而不是周一

因此,在带有
NSDate
NSCalendar
的Objective-C中,我如何实现以下功能:

-(NSDate *)logicalOneYearAgo:(NSDate *)from {
}

换句话说,第n个月的第n个“工作日”(其中“工作日”是星期一、星期二或星期三等)

我不能保证这是最有效的方法,但您可以使用
NSCalendar
NSDateComponents
来完成。将您的
NSDate
实例传递到
[yourCalendar components:yourComponents fromDate:yourDate]
,从组件中减去一年,然后使用
[yourCalendar dateFromComponents:yourComp]


很抱歉没有提供完整的代码,但我已经有一段时间没有使用这些方法了,我不想给您无法使用的代码。

您使用的NSDATE组件如下:

- (NSDate *)logicalOneYearAgo:(NSDate *)from {

    NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];

    NSDateComponents *offsetComponents = [[[NSDateComponents alloc] init] autorelease];
    [offsetComponents setYear:-1];

    return [gregorian dateByAddingComponents:offsetComponents toDate:from options:0];

}

答案很简单。结果是反复试验。答案是这样的

如果一年是闰年,减去365天

如果年份不是闰年,则减去364天。

减去1年。 然后减去1天,直到一周中的同一天结束

每年的“一周中的几天”可以追溯到1天,除非中间有2月29日,否则可以追溯到2天

这是因为一年是52周+1天(+2闰年)

因此,如果你无限期地应用这一逻辑,你将年复一年地在6月16日和5月24日结束

如果你不想发生这种情况,你必须在某个地方记住参考年份,并以此为基础计算

例如,如果“新”的星期一是4天前(因为3年过去了),您可能更愿意选择提前3天的星期一,这样就不会无限期地减去年复一年的天数

希望有帮助。

这在历法计算一节中介绍

具体来说,兴趣的方法是

以苹果为例,从当前日期减去一年,您可以执行以下操作:

NSDate *today = [[NSDate alloc] init];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

/*
  Create a date components to represent the number of years to add to the current date.
  In this case, we add -1 to subtract one year.     
*/

NSDateComponents *addComponents = [[NSDateComponents alloc] init];
addComponents.year = - 1;

return [calendar dateByAddingComponents:addComponents toDate:today options:0];

你必须更准确地定义你的期望是什么;自2011年1月17日起一年后为2010年1月17日。你想要(例如)第n个月的第n个星期一吗?是的,第n个月的第n个“工作日”。这个月有五个星期一,而2010年1月只有四个。在这个日期方案中,2011年1月31日前一年的日期是什么?日历在这里可能很有用。但总的来说,要小心;日历算法在所有情况下都很难正确。我会尝试使用
NSCalendar
将日期分解为
NSDateComponents
使用
NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekdayOrdinalCalendarUnit | NSWeekdayCalendarUnit
。但是我还没有试过这个,所以你必须看看你是否能让它工作。这导致了我在问题中提到的问题。如果“from”是2011年1月17日,那么这个方法将返回2010年1月17日(但是我需要它返回2010年1月18日)。这也导致了我在问题中提到的问题。如果“from”是2011年1月17日,那么这个想法将返回2010年1月17日(不过我需要它返回2010年1月18日)。这甚至不能满足您的要求。这个问题和它的答案是一个火车失事。