I searched about my problem but I did not find any help related...
The story: The user create a continues event by name, start date, end date and note, so saves all fields on the Sqlite database. The both dates format are "yyyy-MM-dd". After that, when user want to do an action on event, the app checks the date that user selected by start and end date and if the entered date is before start date or after end date notifies user.
The problem: I, as an user, created an event from 18-8-2012 to 18-9-2012. Then I put log on 18-8-2012 and I was notified. I debugged app. and I was amazed. the date object from string with format "yyyy-MM-dd" is "2012-08-17 19:30:00 +0000". The code is:
#define kPickerDate @"yyyy-MM-dd"
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:kPickerDate];
NSDate *sDate = [formatter dateFromString:start_date];
NSDate *eDate = [formatter dateFromString:exam_date];
How does app that??????????????
An NSDate
is not just a date, but also a time.
You need to check this at every stage:
NSDateFormatter
for this. Make sure it's time zone is set to UTC.NSDateFormatter
for this. Make sure it's time zone is set to UTC.Only once all three pieces are perfect will you be free of potential bugs here.
To set the time zone of a date formatter, use:
formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"];
Do not try to work around this by adopting local time.
The problem with local times:
The only safe thing to do is use UTC everywhere.
(I actually kind of pity people who live in UTC; they're not forced to shake these bugs out of their apps!)
You can create an NSDate object using a better method. First amend the @interface for NSDate (you can do this anywhere). To do this, put this in your header file.
@interface NSDate (missingFunctions)
+ (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;
@end
Then in the main file put:
@implementation NSDate (missingFunctions)
+ (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:year];
[components setMonth:month];
[components setDay:day];
//BUT MOST IMPORTANTLY:
[components setTimeZone:[NSTimeZone localTimeZone]];
[components setHour:hour];
[components setMinute:minute];
[components setSecond:second];
return [calendar dateFromComponents:components];
}
@end
Then from anywhere in code call (for example):
[NSDate dateWithYear:1969 month:8 day:15];
And it will return an NSDate as per your request in the right time zone. You can change which time zone to use also by reading more about NSTimeZone at the official apple docs.
Note I can't take credit for writing this code, but I can vouch for it working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With