有一个真正令人沮丧的问题似乎没有任何意义。我想要获得2个日期之间的年数。这是我的代码。
// Initialize variable to store calendar
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
// Break out date to year component
NSDateComponents *Components = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit
fromDate:startDate
toDate:endDate
options:0];
// Debugging code
NSLog(@"Debug start date = %@",startDate);
NSLog(@"Debug end date = %@", endDate);
NSLog(@"Debug year = %d",[Components year]);
NSLog(@"Debug month = %d",[Components month]);
NSLog(@"Debug day = %d", [Components day]);
NSLog(@"Debug hours = %d",[Components hour]);
NSLog(@"Debug minutes = %d", [Components minute]);
NSLog(@"Debug seconds = %d", [Components second]);
[gregorian release];
// Check which component to extract and return value accordingly
// Defaults to month for now
if ([datecomponent isEqualToString:@"year"]) {
return [Components year];
}
else {
return [Components month];
}
开始日期和结束日期由UIDatePickers在其他地方设置。他们默认相隔10年。一旦我回到控制结束日期的UIDatePicker并将其移动到1年前。问题将开始出现。这是我将结束日期移回原始日期后我将看到的NSLog的示例。我应该看到其他地方的10年和0年,但我错过了1秒钟。
Debug start date = 2011-08-15 15:55:07 +0000
Debug end date = 2021-08-15 15:55:07 +0000
Debug year = 9
Debug month = 11
Debug day = 30
Debug hours = 23
Debug minutes = 59
Debug seconds = 59
它们之间的开始和结束日期看起来相同,但是由于某些原因,我错过了1秒的时间。有谁知道为什么?
提前致谢!
ADDED
这是我初始化和存储2个日期的方式。
开始日期在viewWillAppear方法中。
- (void)viewWillAppear:(BOOL)animated {
if ([managedObject valueForKeyPath:self.keypath] != nil)
[self.datePicker setDate:[managedObject
valueForKeyPath:keypath] animated:YES];
else
[self.datePicker setDate:[NSDate date] animated:YES];
[self.tableView reloadData];
[super viewWillAppear:animated];
}
同样的类也用于我的结束日期,但是我在NSManagedObject的自定义子类中添加了以下代码: -
- (void)awakeFromInsert {
[super awakeFromInsert];
// Set default date of registration to be today's date
self.startdate = [NSDate date];
NSDate *today = [[NSDate alloc] init]; // I also tried to equate this to self.startdate but there is no difference
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setYear:10];
self.enddate = [gregorian dateByAddingComponents:offsetComponents toDate:today options:0];
}
这会造成任何问题吗?如果是,为什么调试会显示开始日期和结束日期,包括它们的时间完全相同?
答案 0 :(得分:1)
我在一个ViewController中创建了一个带有两个UIDatePickers的简单项目。我将每个UIDatePicker初始化为参考日期,并设置一个操作方法,以便在每次更改其中一个UIDatePickers时计算两个UIDatePickers的日期之间的差异。我将您的代码插入到该方法中,然后在iPhone模拟器中对其进行测试。结果是您的代码输出正好10年:
2011-08-15 11:18:44.225 test[1004:b303] Debug start date = 2001-01-01 00:00:00 +0000
2011-08-15 11:18:44.225 test[1004:b303] Debug end date = 2011-01-01 00:00:00 +0000
2011-08-15 11:18:44.226 test[1004:b303] Debug year = 10
2011-08-15 11:18:44.226 test[1004:b303] Debug month = 0
2011-08-15 11:18:44.227 test[1004:b303] Debug day = 0
2011-08-15 11:18:44.227 test[1004:b303] Debug hours = 0
2011-08-15 11:18:44.227 test[1004:b303] Debug minutes = 0
2011-08-15 11:18:44.228 test[1004:b303] Debug seconds = 0
您是否在使用之前将UIDatePickers初始化为同一时间?默认情况下,UIDatePickers初始化为创建日期(包括小时,分钟,秒等,即使您只在选择器中显示年,月和日)。
您是否有可能以其他方式介绍这种差异?也许你在约会时正在做一些其他的计算或操作?
编辑:
在您添加的代码中,您应该从startdate引用enddate,而不是从另一个日期对象引用enddate。我知道你说它没有什么区别,但是使用startdate比使用startdate更好,而不是假设今天和startdate具有相同的值。
要考虑的另一件事是您的setStartDate:
和setEndDate:
方法。在那些setter方法中,我建议将您不需要的任何精度舍入到0。如果您不允许用户设置比日期更精确的任何内容,则将更高精度设置为0.这样,您将不会在任何两个日期之间留下超过数小时,分钟或秒数。
答案 1 :(得分:0)
我无法在10.7上重现这一点。你在构建什么SDK?
2011-08-15 13:51:44.262 test[9420:707] Debug start date = 2011-08-15 15:55:07 +0000
2011-08-15 13:51:44.263 test[9420:707] Debug end date = 2021-08-15 15:55:07 +0000
2011-08-15 13:51:44.263 test[9420:707] Debug year = 10
2011-08-15 13:51:44.264 test[9420:707] Debug month = 0
2011-08-15 13:51:44.264 test[9420:707] Debug day = 0
2011-08-15 13:51:44.265 test[9420:707] Debug hours = 0
2011-08-15 13:51:44.265 test[9420:707] Debug minutes = 0
2011-08-15 13:51:44.266 test[9420:707] Debug seconds = 0
请注意,这里没有理由提取日,小时,分钟和秒。另外,如果datecomponent
不是year
,那么在您的情况下,这将返回0。我假设你真的意味着它返回120?或者你是以不同的方式使用它?
这是我的完整程序(适用于10.7,命令行模板):
int main (int argc, const char * argv[]) {
@autoreleasepool {
// Initialize variable to store calendar
NSDate *startDate = [NSDate dateWithString:@"2011-08-15 15:55:07 +0000"];
NSDate *endDate = [NSDate dateWithString:@"2021-08-15 15:55:07 +0000"];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
// Break out date to year component
NSDateComponents *components = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit
fromDate:startDate
toDate:endDate
options:0];
// Debugging code
NSLog(@"Debug start date = %@",startDate);
NSLog(@"Debug end date = %@", endDate);
NSLog(@"Debug year = %ld",[components year]);
NSLog(@"Debug month = %ld",[components month]);
NSLog(@"Debug day = %ld", [components day]);
NSLog(@"Debug hours = %ld",[components hour]);
NSLog(@"Debug minutes = %ld", [components minute]);
NSLog(@"Debug seconds = %ld", [components second]);
// [gregorian release];
return 0;
}
}
答案 2 :(得分:0)
在对各种场景进行了相当多的修补之后,这就是我解决问题的方法。
1)由于找到日期之间差异的代码由几个独立的各方检查确定,我已将其作为问题来源消除。
2)我删除了任何试图修改我的应用中日期的代码,这些代码本来就不应该存在。
3)我现在在创建开始日期和结束日期时初始化时间,以确保它们不是基于我在数据库中创建条目时的任意时间。
以下是初始化开始日期的代码段。
NSDate *now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *settomidnight = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:now];
[settomidnight setHour:0];
[settomidnight setMinute:0];
[settomidnight setSecond:0];
startdate = [calendar dateFromComponents:settomidnight];
有了这个,我从NSLog看到时间现在设置为16:00 +0000(转换到我的时区后对我来说是午夜)。问题现在消失了,我不再失去1秒钟。
感谢所有帮助我指导正确道路的人!