在字符串日期前一天将字符串格式的日期转换为nsdate结果

时间:2012-08-29 18:40:43

标签: ios nsdate

我搜索了我的问题,但没有找到任何相关的帮助...

故事: 用户按名称,开始日期,结束日期和注释创建继续事件,因此保存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]; 

应用程序怎么样??????????????

2 个答案:

答案 0 :(得分:10)

NSDate不仅仅是一个日期,也是一个时间。

您需要在每个阶段检查一下:

  • 您的日期在解析时是否正确构建?应该是午夜UTC,而不是当地的午夜。您可能正在使用NSDateFormatter。确保将时区设置为UTC。
  • 您的日期是否正确存储在SQLite中?同样,请确保将其存储为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的更多信息来更改要使用的时区。

注意我不能因为编写此代码而受到赞誉,但我可以保证它可以正常工作。