2012-11-02 115 views
2

鉴于参考日期,我需要找到以下说'星期三'。从参考NSDate获取一周的第二天的NSDate?

要明确一点,如果参考日期是周二说,那么它应该从星期三返回相同的星期。

如果参考日期是星期三或更晚,那么它需要从下一个星期三返回星期。

重要的是它不会在参考日期之后返回星期三。

我一直在寻找使用NSDateComponents,但不知道如何获得一周中必须始终处于未来的第二天。

这是我到目前为止有:

NSDate *referenceDate = [NSDate date]; 
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:referenceDate]; 
[dateComponents setWeekday:4]; // Wednesday 
NSDate *followingWednesday = [calendar dateFromComponents:dateComponents]; 

虽然这段代码不作星期三过去的区别在同一周或下周三,听在于我的问题。

我知道我可以从当前的一周和下一周的一个生成两个日期,然后使用if语句来检查未来哪一个,但是这看起来像很多代码来做一件简单的事情。

有没有更好的方法?

任何帮助,将不胜感激。


更新

似乎设置平日实际上并不影响由NSCalendar的dateComponents:方法返回的日期。我上面的示例代码返回相同的日期,无论星期几设置什么。

所以现在我更难倒了。

+0

如果日期过去的话加7天怎么样,否则就放任它吧? – tazzix

+0

是的,这基本上就是我在做的事情,但我很想知道他们是否是一种更好的方式,说'让我下个星期三',而不必写很多额外的逻辑。我希望有一些我错过了NSDateComponents类。可能没有那么好,我会按照我的方式去做。 – Camsoft

回答

4

我会做这样的:

NSDate *referenceDate = [NSDate date]; 
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit|NSMonthCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit) fromDate:referenceDate]; 

int targetWeekday = 4; 

if (dateComponents.weekday >= targetWeekday) 
{ 
    dateComponents.week++; 
} 

dateComponents.weekday = targetWeekday; 
NSDate *followingTargetDay = [calendar dateFromComponents:dateComponents]; 
+0

这不起作用,请参阅我的原始问题的更新。 – Camsoft

+0

是否在向组件提供日历时添加了“NSWeekdayCalendarUnit”和“NSWeekCalendarUnit”标志?您可能还需要删除'NSDayCalendarUnit'标志。我现在无法测试它。 – Tobi

+0

现货,我不得不删除'NSDayCalendarUnit'。谢谢! – Camsoft

2

你必须要经过一个NSDateFormatter。你可以做这样的事来计算下一个周末。我不知道你想要什么,但是这里有一个例子:

NSDate *referenceDate = [NSDate date]; 
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
NSDateComponents *mincomp = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:referenceDate]; 
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateFormat:@"e"]; 
while ([[formatter stringFromDate:[cal dateFromComponents:mincomp]] intValue] != 4) 
    mincomp.day += 1; 
[formatter setDateFormat:@"yyyy-MM-dd"]; 
NSLog(@"next wednesday = %@", [formatter stringFromDate:[cal dateFromComponents:mincomp]]); 
+0

这很有趣,事实上它的工作原理虽然看起来很奇怪,但你必须依靠'NSDateFormatter'来完成这个任务。是否有任何使用'NSDateFormatter'的警告? – Camsoft

+0

据我所知,没有。 – Martol1ni

1

使用dateWithNaturalLanguageString

NSDate *date = [NSDate dateWithNaturalLanguageString:@"next Wednesday"]; 
NSLog(@"%@",date); 

注意dateWithNaturalLanguageString

创建并返回一个NSDate对象集到给定字符串指定的日期和时间。

+ (id)dateWithNaturalLanguageString:(NSString *)string 

参数

包含日期的口语化的规范,如“上周二在吃饭,”“下午3点12月31日的字符串, 2001“,”12/31/01“或”31/12/01“。

+0

很想使用它,不幸的是,这仅支持MacOS X.对不起,应该明确表示我在使用iOS 5.请参阅标签。 – Camsoft

+0

此外,您应该考虑这适用于首选英文版的用户,这种情况对于使用os x的用户来说是个好方法。 –

+0

它也适用于ios检查出 –

0

我还没有得到很好地捆绑了整个事情,因为我昨天不约而同地制定了实施不同的计算机上,但大致是:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateFormat:@"e"]; 
NSInteger day = [[formatter stringFromDate:theDate] integerValue]; 
NSInteger offsetDays = (targetDay - day); // targetDay is 4 for Wednesday 
if (offsetDays < 0) offsetDays += 7; 
NSDate* resultDate = [theDate dateByAddingTimeInterval:offsetDays * secondsInADay]; 

(该offsetDays计算可能有点失控 - 诸如此类的事情,需要更多的思考比可在这个时间上午)

+0

我不确定这个解决方案能否正确处理时区和夏令时。 – Camsoft

+0

@Camsoft - 无论时区如何,上述都应该可以正常工作,因为它甚至会以24小时为单位进行补偿。 (格式化程序需要设置为您关心的TZ,当然要获得正确的一天。)但是,DST更改需要单独的努力。 –

-1

This guy nailed it.

适合OP:

NSDate *refDate = [NSDate date]; // or whatever 
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
[gregorian setLocale:[NSLocale currentLocale]]; 

NSDateComponents *nowComponents = [gregorian components:NSYearCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:refDate]; 
int wednesday = 4; 
if(nowComponents.weekday >= wednesday) { 
    [nowComponents setWeek: nowComponents.week + 1]; // Next week 
} 
[nowComponents setWeekday:wednesday]; // Wednesday 
[nowComponents setHour:8]; // Specific time (if desired) 
[nowComponents setMinute:0]; 
[nowComponents setSecond:0]; 

NSDate *nextWednesday = [gregorian dateFromComponents:nowComponents]; 

如您所述,即使参考日期是星期三,每次都会得到“下周三”。

编辑:修复了评论中指出的错误。

+0

假设refDate是星期二,并且您使用此代码:未来将有8天的星期三,而不是将来1天的星期三,OP要求提供。 – SG1

+0

Bah。好抓,傻我。如@Tobi所做的那样,需要有条件地增加一周。 – dooleyo