我搜索了我的问题,但没有找到任何相关的帮助...
故事: 用户按名称,开始日期,结束日期和注释创建继续事件,因此保存Sqlite数据库上的所有字段。两种日期格式均为“yyyy-MM-dd”。 之后,当用户想要对事件执行操作时,应用程序会检查用户在开始日期和结束日期之间选择的日期,以及输入的日期是在开始日期之前还是在结束日期之后通知用户。
问题: 作为用户,我在2012年8月18日至2012年9月18日期间创建了一个活动。然后我把登录在18-8-2012,我收到了通知。我调试了应用程序。我很惊讶格式为“yyyy-MM-dd”的字符串中的日期对象为“2012-08-17 19:30:00 +0000”。 代码是:
#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];
应用程序怎么样??????????????
答案 0 :(得分:10)
NSDate
不仅仅是一个日期,也是一个时间。
您需要在每个阶段检查一下:
NSDateFormatter
。确保将时区设置为UTC。NSDateFormatter
。确保将时区设置为UTC。只有这三件都完美无缺,你才能摆脱潜在的错误。
要设置日期格式化程序的时区,请使用:
formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"];
不要试图通过采用当地时间来解决这个问题。
当地时间的问题:
唯一安全的做法是在任何地方使用UTC。
(我实际上生活在UTC中的人很可惜;他们不会被迫从他们的应用程序中甩掉这些错误!)
答案 1 :(得分:1)
您可以使用更好的方法创建NSDate对象。首先修改NSDate的@interface(您可以在任何地方执行此操作)。为此,请将其放在头文件中。
@interface NSDate (missingFunctions)
+ (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;
@end
然后在主文件中输入:
@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
然后从代码调用的任何地方(例如):
[NSDate dateWithYear:1969 month:8 day:15];
它将根据您在正确时区的请求返回NSDate。您可以通过在官方Apple文档中阅读有关NSTimeZone的更多信息来更改要使用的时区。
注意我不能因为编写此代码而受到赞誉,但我可以保证它可以正常工作。