NSCalendar первый день недели
Кто-нибудь знает, есть ли способ установить первый день недели в NSCalendar, или есть календарь, который уже имеет понедельник в качестве первого дня недели, а не в воскресенье.
В настоящее время я работаю над приложением, основанным на работе на неделю, и его нужно начинать в понедельник, а не в воскресенье. Я, скорее всего, поработаю над этим, но будет много угловых дел. Я бы предпочел, чтобы платформа сделала это для меня.
Заранее спасибо
Вот код, который я использую. это субботу, так что я надеюсь, что будний день будет 6, а не 7. это будет означать, что воскресенье будет 7, а не перевернется на 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;
Ответы
Ответ 1
Изменить: Это не проверяет край, где начинается начало недели в предыдущем месяце. Некоторые обновленные коды для этого: fooobar.com/questions/56257/...
Если кто-то все еще обращает на это внимание, вам нужно использовать
ordinalityOfUnit:inUnit:forDate:
и установите firstWeekday на 2. (1 == Воскресенье и 7 == Суббота)
Здесь код:
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);
Помните, что ординалы для будних дней начинаются с 1 в первый день недели, а не ноль.
Ссылка документации.
Ответ 2
Этот код создает дату, установленную в понедельник текущей недели:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *today = [NSDate date];
NSDate *beginningOfWeek = nil;
BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek
interval:NULL forDate: today];
Ответ 3
setFirstWeekday: в объекте NSCalendar.
Устанавливает индекс первого дня недели для получателя.
- (void)setFirstWeekday:(NSUInteger)weekday
Должен сделать трюк.
Ответ 4
По-моему, эти настройки должны быть динамическими в соответствии с пользовательской локалью.
Поэтому следует использовать:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setLocale:[NSLocale currentLocale]];
Это приведет к тому, что календарь автоматически установит первый день недели в соответствии с пользовательской локалью. Если вы не разрабатываете приложение для определенной цели/пользовательской локали (или предпочитаете, чтобы пользователь мог выбрать этот день).
Ответ 5
Проблема с ответом Криса - это краевой случай, когда начало недели начинается в предыдущем месяце. Вот еще один простой код, и он также проверяет регистр:
// 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];
}
Ответ 6
Я сделал это вот так.
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
Ответ 7
У меня были проблемы с множеством ответов здесь., возможно, это был только я.,
Вот ответ, который работает для меня:
- (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];
}
Update:
Как указано (в другом месте) by @vikingosegundo, в целом лучше всего разрешить местному определять, какой день является началом недели, однако в этом случае OP просил начать неделю в понедельник, поэтому мы копируем системный календарь и переопределяем firstWeekDay.
Ответ 8
Я вижу недоразумение в других сообщениях. Первый день недели, в зависимости от того, что имеет место, имеет номер 1, а не 0. По умолчанию воскресенье = 1, как в "Руководстве по программированию" Введение в дату и время "для Cocoa: Календарные вычисления":
"Значение дня недели для воскресенья в григорианском календаре равно 1"
Для понедельника в качестве первого рабочего дня единственным средством, которое у меня есть, является условие грубой силы, чтобы исправить расчет
NSCalendar *cal=[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [cal components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
// set to 7 if it Sunday otherwise decrease weekday number
NSInteger weekday=[comps weekday]==1?7:[comps weekday]-1;
Ответ 9
Ниже также рассматривается краевой случай,
- (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];
}
Ответ 10
Попробуйте следующее:
NSCalendar *yourCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]
[yourCal setFirstWeekday:0];
Ответ 11
... есть календарь, который уже имеет понедельник в качестве первого дня недели, а не в воскресенье.
Когда-нибудь будет.
Ответ 12
Iv выяснил способ отображения любого имени дня недели с помощью nscalender.. используя следующий код.
Просто откройте консоль из строки меню xcode, чтобы увидеть результаты. Копия Вставьте следующий код в свой метод viewDidLoad, чтобы получить первый день недели.
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);
Выход будет:
date: 02/11/2010 :Thursday
First_date: 02/07/2010 :Sunday
так как я запустил эту программу 2/11/2010, u получит желаемый результат в зависимости от текущей даты.
Аналогично, если u хочет получить первый рабочий день недели, то есть в понедельник, а затем немного измените код:
ИЗМЕНИТЬ: [components setDay:([components day]-([components weekday]-1))];
К
[components setDay:([components day]-([components weekday]-2))];
чтобы получить дату понедельника на эту неделю.
Аналогично, вы можете попытаться найти дату любого из семи рабочих дней, изменив целое число -1, -2 и так далее...
Надеюсь, что на вопрос ответят.
Спасибо,
Bonson Dias
Ответ 13
Мой простой способ сделать это - получить понедельник = 0, воскресенье = 6:
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
NSInteger dayNumStartingFromMonday = ([dateComponents weekday] - 2 + 7) % 7; //normal: Sunday is 1, Monday is 2
Ответ 14
Календар ISO 8601, по-видимому, имеет первый день недели, установленный в понедельник по умолчанию.
Ответ 15
Использование календаря nextWeekend (iOS 10 или новее) и ordinality (спасибо @kris-markel). Я получил понедельник в качестве первой недели для календаря en_US.
Вот пример с возвратом в 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
}
}
Ответ 16
Вы можете просто изменить .firstWeekday
календаря.
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
calendar.firstWeekday = 2;
Затем используйте rangeOfUnit:startDate:interval:forDate:
, чтобы получить первый день
NSDate *startOfWeek;
[calendar rangeOfUnit:NSCalendarUnitWeekOfYear startDate:&startOfWeek interval:nil forDate:[NSdate date]];