NSCalendar primo giorno della settimana

Qualcuno sa se c’è un modo per impostare il primo giorno della settimana su un NSCalendar, o c’è un calendario che ha già lunedì come primo giorno della settimana, invece di domenica. Attualmente sto lavorando a un’app che si basa su una settimana di lavoro e che deve iniziare il lunedì, non la domenica. Molto probabilmente farò del lavoro per ovviare a questo, ma ci saranno molti casi d’angolo. Preferirei che la piattaforma lo facesse per me.

Grazie in anticipo

Ecco alcuni dei codici che sto usando. è sabato adesso, quindi quello che spero è che il giorno della settimana sarebbe 6, invece di 7. Ciò significherebbe che domenica sarebbe 7 invece di passare a 0

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [gregorian setFirstWeekday:0]; unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit; NSDateComponents *todaysDate = [gregorian components:unitFlags fromDate:[NSDate date]]; int dayOfWeek = todaysDate.weekday; 

    Modifica: non controlla il caso limite in cui inizia l’inizio della settimana nel mese precedente. Qualche codice aggiornato per coprire questo: https://stackoverflow.com/a/14688780/308315


    Nel caso qualcuno stia ancora prestando attenzione a questo, è necessario utilizzare

     ordinalityOfUnit:inUnit:forDate: 

    e impostare prima il Giorno 2 a 2. (1 == domenica e 7 == sabato)

    Ecco il codice:

     NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; [gregorian setFirstWeekday:2]; // Sunday == 1, Saturday == 7 NSUInteger adjustedWeekdayOrdinal = [gregorian ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:[NSDate date]]; NSLog(@"Adjusted weekday ordinal: %d", adjustedWeekdayOrdinal); 

    Ricorda, gli ordinali per i giorni della settimana iniziano da 1 per il primo giorno della settimana, non zero.

    Link alla documentazione

    Questo codice crea una data impostata a lunedì della settimana corrente:

     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *today = [NSDate date]; NSDate *beginningOfWeek = nil; BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek interval:NULL forDate: today]; 

    setFirstWeekday: sull’object NSCalendar. Imposta l’indice del primo giorno della settimana per il destinatario.

     - (void)setFirstWeekday:(NSUInteger)weekday 

    Dovrebbe fare il trucco.

    A mio parere, queste impostazioni dovrebbero essere dinamiche in base alle impostazioni locali dell’utente. Quindi si dovrebbe usare:

     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [gregorian setLocale:[NSLocale currentLocale]]; 

    Ciò farà sì che il calendario imposti automaticamente il primo giorno della settimana secondo le impostazioni locali dell’utente. A meno che tu non stia sviluppando la tua app per uno specifico scopo / utente locale (o preferisci consentire all’utente di scegliere questo giorno).

    Ho avuto problemi con molte risposte qui. . Forse ero solo io. .

    Ecco una risposta che funziona per me:

     - (NSDate*)firstDayOfWeek { NSCalendar* cal = [[NSCalendar currentCalendar] copy]; [cal setFirstWeekday:2]; //Override locale to make week start on Monday NSDate* startOfTheWeek; NSTimeInterval interval; [cal rangeOfUnit:NSWeekCalendarUnit startDate:&startOfTheWeek interval:&interval forDate:self]; return startOfTheWeek; } - (NSDate*)lastDayOfWeek { NSCalendar* cal = [[NSCalendar currentCalendar] copy]; [cal setFirstWeekday:2]; //Override locale to make week start on Monday NSDate* startOfTheWeek; NSTimeInterval interval; [cal rangeOfUnit:NSWeekCalendarUnit startDate:&startOfTheWeek interval:&interval forDate:self]; return [startOfTheWeek dateByAddingTimeInterval:interval - 1]; } 

    Aggiornare:

    Come sottolineato ( altrove ) da @vikingosegundo, in generale è meglio lasciare che il locale determini quale giorno è l’inizio della settimana, tuttavia in questo caso l’OP chiedeva che l’inizio della settimana si verifichi il lunedì, quindi copiamo il calendario di sistema e sovrascrive il primoGestile.

    Il problema con la risposta di Kris è il caso limite in cui l’inizio della settimana inizia nel mese precedente. Ecco un codice più semplice e controlla anche il caso limite:

     // Finds the date for the first day of the week - (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate { NSCalendar *calendar = [NSCalendar currentCalendar]; // Edge case where beginning of week starts in the prior month NSDateComponents *edgeCase = [[NSDateComponents alloc] init]; [edgeCase setMonth:2]; [edgeCase setDay:1]; [edgeCase setYear:2013]; NSDate *edgeCaseDate = [calendar dateFromComponents:edgeCase]; NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:edgeCaseDate]; [components setWeekday:1]; // 1 == Sunday, 7 == Saturday [components setWeek:[components week]]; NSLog(@"Edge case date is %@ and beginning of that week is %@", edgeCaseDate , [calendar dateFromComponents:components]); // Find Sunday for the given date components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate]; [components setWeekday:1]; // 1 == Sunday, 7 == Saturday [components setWeek:[components week]]; NSLog(@"Original date is %@ and beginning of week is %@", givenDate , [calendar dateFromComponents:components]); return [calendar dateFromComponents:components]; } 

    L’ho fatto in questo modo

     NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *today = [NSDate date]; NSDateComponents *compForWeekday = [gregorian components:(NSWeekdayCalendarUnit) fromDate:today]; NSInteger weekDayAsNumber = [compForWeekday weekday]; // The week day as number but with sunday starting as 1 weekDayAsNumber = ((weekDayAsNumber + 5) % 7) + 1; // Transforming so that monday = 1 and sunday = 7 

    Vedo incomprensioni negli altri messaggi. Il primo giorno della settimana, qualunque esso sia, ha il numero 1 non 0. Per impostazione predefinita, Sunday = 1, come nella “Introduzione alla guida di programmazione di data e ora per il cocoa: calcoli in calendario”:

    “Il valore del giorno della settimana per il calendario gregoriano è 1”

    Per il lunedì come primo giorno di lavoro l’unico rimedio che ho è la condizione di forza bruta per fissare il calcolo

     NSCalendar *cal=[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *comps = [cal components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; // set to 7 if it's Sunday otherwise decrease weekday number NSInteger weekday=[comps weekday]==1?7:[comps weekday]-1; 

    Qui di seguito copre anche il caso limite,

     - (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate]; [components setWeekday:2]; // 1 == Sunday, 7 == Saturday if([[calendar dateFromComponents:components] compare: curDate] == NSOrderedDescending) // if start is later in time than end { [components setWeek:[components week]-1]; } return [calendar dateFromComponents:components]; } 

    Prova questo:

     NSCalendar *yourCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] [yourCal setFirstWeekday:0]; 

    … c’è un calendario che ha già lunedì come primo giorno della settimana, invece di domenica.

    Un giorno, ci sarà.

    Iv ha trovato il modo di visualizzare il nome di ogni giorno della settimana usando nscalender..utilizzando il seguente codice .. Basta aprire la console dalla barra dei menu di xcode per vedere i risultati. Copia Incolla il seguente codice nel tuo metodo viewDidLoad per ottenere il primo giorno della settimana

     NSDate *today = [NSDate date]; NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"MM/dd/yyyy :EEEE"]; NSString *dateString = [dateFormat stringFromDate:today]; NSLog(@"date: %@", dateString); [dateFormat release]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today]; [components setDay:([components day]-([components weekday]-1))]; NSDate *beginningOfWeek = [gregorian dateFromComponents:components]; NSDateFormatter *dateFormat_first = [[NSDateFormatter alloc] init]; [dateFormat_first setDateFormat:@"MM/dd/yyyy :EEEE"]; NSString *dateString_first = [dateFormat_first stringFromDate:beginningOfWeek]; NSLog(@"First_date: %@", dateString_first); 

    L’uscita sarà:

      date: 02/11/2010 :Thursday First_date: 02/07/2010 :Sunday 

    dal momento che ho eseguito questo programma il 2/11/2010, otterremo l’output desiderato in base alla data corrente.

    Allo stesso modo se si desidera ottenere il primo giorno lavorativo della settimana, ad esempio la data di lunedì, è sufficiente modificare leggermente il codice:

    CHANGE: [components setDay:([components day]-([components weekday]-1))];

    TO [components setDay:([components day]-([components weekday]-2))];

    per ottenere la data di lunedì per quella settimana ..

    Allo stesso modo puoi provare a trovare la data di uno dei sette giorni lavorativi cambiando il numero intero -1, -2 e così via …

    Spero che la tua domanda sia esaudita ..

    Grazie, Bonson Dias

    Il mio modo semplice per farlo è ottenere lunedì = 0, domenica = 6:

      NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; NSInteger dayNumStartingFromMonday = ([dateComponents weekday] - 2 + 7) % 7; //normal: Sunday is 1, Monday is 2 

    Il calendario ISO 8601 sembra avere il primo giorno della settimana impostato su lunedì per impostazione predefinita.

    Utilizzo del calendario nextWeekend (iOS 10 o successivo) e ordinalità (grazie a @kris-markel). Ho ottenuto il lunedì come primo della settimana per il calendario en_US.

    Ecco un esempio di esso con fallback a firstWeekday:

     extension Calendar { var firstWorkWeekday: Int { guard #available(iOS 10.0, *) else{ return self.firstWeekday } guard let endOfWeekend = self.nextWeekend(startingAfter: Date())?.end else { return self.firstWeekday } return self.ordinality(of: .weekday, in: .weekOfYear, for: endOfWeekend) ?? self.firstWeekday } } 

    Puoi semplicemente cambiare il primo .firstWeekday di calendario del calendario.

     NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; calendar.firstWeekday = 2; 

    Quindi utilizzare rangeOfUnit:startDate:interval:forDate: per ottenere il primo giorno

     NSDate *startOfWeek; [calendar rangeOfUnit:NSCalendarUnitWeekOfYear startDate:&startOfWeek interval:nil forDate:[NSdate date]];