有没有人知道是否有办法在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;
答案 0 :(得分:77)
编辑:这不会检查上周开始的一周开始的边缘情况。一些更新的代码涵盖了这一点:https://stackoverflow.com/a/14688780/308315
如果有人仍在关注此事,您需要使用
ordinalityOfUnit:inUnit:forDate:
并将firstWeekday设为2.(1 == Sunday和7 == Saturday)
以下是代码:
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 :(得分:17)
此代码构造一个设置为当前星期一的日期:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *today = [NSDate date];
NSDate *beginningOfWeek = nil;
BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek
interval:NULL forDate: today];
答案 2 :(得分:12)
setFirstWeekday:。 设置接收者的第一个工作日的索引。
- (void)setFirstWeekday:(NSUInteger)weekday
应该做的伎俩。
答案 3 :(得分:10)
在我看来,根据用户区域设置,此设置应该是动态的。 因此,应该使用:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setLocale:[NSLocale currentLocale]];
这将使日历根据用户区域设置自动设置第一周。除非您为特定目的/用户区域设置开发应用程序(或者更愿意让用户选择这一天)。
答案 4 :(得分:8)
我这样做了。
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
答案 5 :(得分:8)
我在这里遇到了很多答案。 。也许只是我。 。
这是一个适合我的答案:
- (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];
}
<强>更新强>
正如@vikingosegundo指出的那样(elsewhere),一般来说最好让当地人决定哪一天是本周的开始,但是在这种情况下,OP要求本周开始星期一发生,因此我们复制系统日历,并覆盖firstWeekDay。
答案 6 :(得分:7)
Kris回答的问题是本周初在上个月开始的边缘情况。这是一些更简单的代码,它还检查边缘情况:
// 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];
}
答案 7 :(得分:3)
我看到其他消息中的误解。第一个工作日,以它为准,数字1不为0.默认星期日= 1,如“可可日期和时间编程指南简介:日历计算”:
“格里高利历中星期日的工作日值为1”
对于星期一作为第一个工作日,我唯一的补救措施是强力条件来解决计算
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;
答案 8 :(得分:1)
下面还介绍了边缘情况,
- (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];
}
答案 9 :(得分:0)
Swift解决方案(请注意,使用 .yearForWeekOfYear ,而不是.year):
let now = Date()
let cal = Calendar.current
var weekComponents = cal.dateComponents([.yearForWeekOfYear, .weekOfYear,
.weekday], from: now)
//weekComponents.weekday = 1 // if your week starts on Sunday
weekComponents.weekday = 2 // if your week starts on Monday
cal.date(from: weekComponents) // returns date with first day of the week
答案 10 :(得分:0)
您只需更改日历的.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]];
答案 11 :(得分:0)
使用日历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
}
}
答案 12 :(得分:0)
ISO 8601日历似乎默认情况下将其第一个工作日设置为星期一。
答案 13 :(得分:0)
我这样做的简单方法是让星期一= 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 :(得分:0)
我发现使用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
因为我在2010年11月2日运行了这个程序,你将根据当前日期获得所需的输出。
同样,如果你想获得一周的第一个工作日,即周一的日期,那么只需修改一下代码:
更改:[components setDay:([components day]-([components weekday]-1))];
要
[components setDay:([components day]-([components weekday]-2))];
获取周一的星期日..
同样,您可以通过更改整数-1,-2等来尝试查找七个工作日中任何一个的日期......
希望你的问题得到解答..
谢谢, Bonson Dias
答案 15 :(得分:0)
试试这个:
NSCalendar *yourCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]
[yourCal setFirstWeekday:0];
答案 16 :(得分:-1)
...是否有一个日历已经是星期一作为一周的第一天,而不是星期日。