Got a really frustrating problem that doesn't seem to make any sense. I'm trying to get the number of years between 2 dates. Here is my code.
// 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];
}
The start and end dates are set by UIDatePickers elsewhere. They would default to being 10 years apart. Once I go back to the UIDatePicker that controls the end date and move that up to 1 year earlier. The problem will start appearing. This is an example of the NSLog I will see after I move the end date back to the original date. I should see 10 years and 0 everywhere else but I'm missing 1 second in time.
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
The start and end dates look identical saved for the 10 years between them to me but for some reason, I'm missing 1 second of time. Does anyone know why?
Thanks in advance!
ADDED
Here is the way I have initialized and stored the 2 dates.
The start date is in the viewWillAppear method.
- (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];
}
The same class is also used for my end date however I have also added the following code in my custom subclass of 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];
}
Would this have caused any problems? If yes, why would the debug show the start and end dates including their times as exactly the same?
After quite a bit of tinkering with various scenarios, this is the way which I solved the issue.
1) Since the code to find the difference between the dates checks out ok by several independent parties, I have eliminated it as a source of problem.
2) I have removed any code that attempts to modify the dates in my app which should not have been there in the first place.
3) I now initialize the time as well when I create the start and end dates so as to ensure that they are not some arbitrary time based on when I create the entry in database.
Here's the code snippet to initialize the start date.
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];
With this, I see from the NSLog that the time is now set as 16:00 +0000 (which is midnight for me after converting to my timezone). The problem has now gone away and I'm no longer losing my 1 second.
Thanks to all who have helped guide me on the right path!