Вычисление «в прошлую пятницу» с NSDATE + NSDATECOMPONTERS
-
15-10-2019 - |
Вопрос
У меня есть некоторые проблемы с вычислением конкретных дней по сравнению с текущей датой, используя NSDATE и NSDateComponents. Например, допустим, я хочу в прошлую пятницу. Я попробовал следующее:
NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit) fromDate:[NSDate date]];
[components setHour:0];
[components setMinute:0];
[components setSecond:0];
[components setWeekday:6]; //Friday
[components setWeek:[components week] - 1]; //Last Week
return [[NSCalendar currentCalendar] dateFromComponents:components];
Но это просто возвращает текущую дату, как будто не может понять, о чем я прошу.
Это кажется, что это должно быть достаточно просто, но я просто не заставляю это работать. Есть указатели?
Решение
Как насчет чего -то подобного:
NSDate* today = [NSDate date];
NSDateComponents* comps = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:today];
// do the modulo arithmetic to determine the delta days to last Friday
NSInteger weekday = [comps weekday];
NSInteger deltaDays = 0; // left as exercise, I am hungry for lunch...
NSDateComponents* delta = [[NSDateComponents alloc] init];
[delta setDay:deltaDays];
NSDate* lastFriday = [[NSCalendar currentCalendar] dateByAddingComponents:delta toDate:today options:0];
[delta release];
Другие советы
Используйте этот код:
- (NSDate *)lastDayOfMonthWithDate:(NSDate *)date
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSYearCalendarUnit | NSMonthCalendarUnit fromDate:date];
components.month += 1;
components.day = 0;
NSDate *lastDayOfMonth = [[NSCalendar currentCalendar] dateFromComponents:components];
return lastDayOfMonth;
}
- (NSDate *)lastFridayOfMonthWithDate:(NSDate *)date
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit fromDate:[self lastDayOfMonthWithDate:date]];
if (components.weekday >= 6) {
components.day -= components.weekday - 6;
} else {
components.day += 6 - components.weekday - 7;
}
NSDate *lastFridayOfMonth = [[NSCalendar currentCalendar] dateFromComponents:components];
return lastFridayOfMonth;
}
Я написал эту функцию:
- (NSInteger)lastOccurrenceOfWeekdayWithNumber:(NSInteger)weekdayNumber inMonthForDate:(NSDate *)date {
NSCalendarUnit units = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal;
NSRange range = [_calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
NSDateComponents *dateComponents = [_calendar components:units fromDate:date];
dateComponents.day = range.length;
date = [_calendar dateFromComponents:dateComponents];
dateComponents = [_calendar components:units fromDate:date];
while (dateComponents.weekday != weekdayNumber) {
dateComponents.day -= 1;
date = [_calendar dateFromComponents:dateComponents];
dateComponents = [_calendar components:units fromDate:date];
}
return dateComponents.weekdayOrdinal;
}
weekdayNumber
1, когда вы ищете воскресенье. 2 на понедельник.
Если вы хотите найти в прошлую пятницу в октябре, вы можете использовать это:
[self lastOccurrenceOfWeekdayWithNumber:6 inMonthForDate:date];
Где дата, скажем, 11 октября, 2016 года или в любой другой день октября.
Не связан с StackOverflow