Pregunta

Estoy teniendo algunos problemas para calcular los días específicos relativos a la fecha actual utilizando NSDate y NSDateComponents. Por ejemplo, digamos que yo quiero el pasado viernes. He intentado lo siguiente:

    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];

Pero eso simplemente devuelve la fecha actual, ya que si no se puede averiguar lo que estoy pidiendo.

Esto se siente como tiene que ser lo suficientemente simple, pero yo no estoy conseguir que funcione. Cualquier punteros?

¿Fue útil?

Solución

¿Qué tal algo como esto:

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];

Otros consejos

Use this code:

- (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;
}

I wrote this function:

- (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 is 1 when you are looking for Sunday. 2 for Monday.

If you want to find last Friday in October you can use this:

[self lastOccurrenceOfWeekdayWithNumber:6 inMonthForDate:date];

where date is let's say the 11th of October, 2016 or any other day of October.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top