指定日期的月值错误?
Month value coming wrong for a specified date?
以下是我的代码:
NSDateComponents *componenetsForEnd = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:endDate];
NSInteger endDay = [componenetsForEnd day];
NSInteger endMonth = [componenetsFoeEnd month];
NSInteger endDayValue = componenetsForEnd.weekday;
现在:当 endDate = 2015-08-31 23:59:59 +0000 时,我得到的月份是 9!这会导致错误的 endDayValue。这里出了什么问题?
编辑:
这是我计算结束日期的方法:
NSDate *endDate = [self endOfMonthForDate:todayDate];
此方法使用今天的日期 [NSDate date],它是这样的:
- (NSDate *) dateByAddingMonths: (NSInteger) monthsToAdd andDate: (NSDate *)date
{
NSCalendar * calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSDateComponents * months = [[NSDateComponents alloc] init];
[months setMonth: monthsToAdd];
return [calendar dateByAddingComponents: months toDate: date options: 0];
}
- (NSDate *) endOfMonthForDate: (NSDate *)date
{
NSCalendar * calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSDate * plusOneMonthDate = [self dateByAddingMonths: 1 andDate:date];
NSDateComponents * plusOneMonthDateComponents = [calendar components: NSYearCalendarUnit | NSMonthCalendarUnit fromDate: plusOneMonthDate];
NSDate * endOfMonth1 = [[calendar dateFromComponents: plusOneMonthDateComponents] dateByAddingTimeInterval: -1]; // One second before the start of next month
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:endOfMonth1];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:endOfMonth1];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* endOfMonth = [[NSDate alloc] initWithTimeInterval:interval sinceDate:endOfMonth1];
return endOfMonth;
}
还尝试执行这些操作以在 systemTimeZone 中使用 dateFormatter 创建 NSDateComponents 和 NSDate:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *endDateString = [dateFormatter stringFromDate:endDate];
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc]init];
[dateFormatter2 setTimeZone:[NSTimeZone systemTimeZone]];
dateFormatter2.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *endDateProper = [dateFormatter2 dateFromString:endDateString];
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *componenetsForEnd = [greCalendar components:NSWeekdayCalendarUnit | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:endDateProper];
[componenetsForEnd setTimeZone:[NSTimeZone systemTimeZone]];
而不是使用当前日历
[NSCalendar currentCalendar]
您可以使用:
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
问题出在我认为是这样的事实:在计算日、月或小时、分钟和秒时,您需要指定 dateComponents 的时区是 UTC,即 GMT。但是,我的 endDateProper 在系统时区。
所以,这样做对我有用:
NSDateComponents *componenetsForEnd = [greCalendar componentsInTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"] fromDate:endDateProper];
以下是我的代码:
NSDateComponents *componenetsForEnd = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:endDate];
NSInteger endDay = [componenetsForEnd day];
NSInteger endMonth = [componenetsFoeEnd month];
NSInteger endDayValue = componenetsForEnd.weekday;
现在:当 endDate = 2015-08-31 23:59:59 +0000 时,我得到的月份是 9!这会导致错误的 endDayValue。这里出了什么问题?
编辑:
这是我计算结束日期的方法:
NSDate *endDate = [self endOfMonthForDate:todayDate];
此方法使用今天的日期 [NSDate date],它是这样的:
- (NSDate *) dateByAddingMonths: (NSInteger) monthsToAdd andDate: (NSDate *)date
{
NSCalendar * calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSDateComponents * months = [[NSDateComponents alloc] init];
[months setMonth: monthsToAdd];
return [calendar dateByAddingComponents: months toDate: date options: 0];
}
- (NSDate *) endOfMonthForDate: (NSDate *)date
{
NSCalendar * calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone systemTimeZone]];
NSDate * plusOneMonthDate = [self dateByAddingMonths: 1 andDate:date];
NSDateComponents * plusOneMonthDateComponents = [calendar components: NSYearCalendarUnit | NSMonthCalendarUnit fromDate: plusOneMonthDate];
NSDate * endOfMonth1 = [[calendar dateFromComponents: plusOneMonthDateComponents] dateByAddingTimeInterval: -1]; // One second before the start of next month
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:endOfMonth1];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:endOfMonth1];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* endOfMonth = [[NSDate alloc] initWithTimeInterval:interval sinceDate:endOfMonth1];
return endOfMonth;
}
还尝试执行这些操作以在 systemTimeZone 中使用 dateFormatter 创建 NSDateComponents 和 NSDate:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *endDateString = [dateFormatter stringFromDate:endDate];
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc]init];
[dateFormatter2 setTimeZone:[NSTimeZone systemTimeZone]];
dateFormatter2.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *endDateProper = [dateFormatter2 dateFromString:endDateString];
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *componenetsForEnd = [greCalendar components:NSWeekdayCalendarUnit | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:endDateProper];
[componenetsForEnd setTimeZone:[NSTimeZone systemTimeZone]];
而不是使用当前日历
[NSCalendar currentCalendar]
您可以使用:
NSCalendar *greCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
问题出在我认为是这样的事实:在计算日、月或小时、分钟和秒时,您需要指定 dateComponents 的时区是 UTC,即 GMT。但是,我的 endDateProper 在系统时区。
所以,这样做对我有用:
NSDateComponents *componenetsForEnd = [greCalendar componentsInTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"] fromDate:endDateProper];