【问题标题】:iphone sqlite NSDate bugiphone sqlite NSDate 错误
【发布时间】:2010-12-23 20:21:14
【问题描述】:

我在我的 iphone 应用程序中使用核心数据,但在某些情况下,我使用 sqlite 来访问数据并且我遇到了 NSDate 的问题。

NSDate *now = [NSDate date];
        NSCalendar *calender = [NSCalendar currentCalendar];;
        NSDateComponents *comp = [calender components:NSYearCalendarUnit fromDate:now];
        [comp setDay:1];
        [comp setMonth:1];
        NSDate *yearAgo = [calender dateFromComponents:comp];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date > %@",yearAgo];

此代码有效并从年初开始选择记录,但如果我使用 sqlite 原始查询

NSDate *current=[NSDate date];
            NSDateComponents *comps = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit |NSYearCalendarUnit) fromDate:current];
            [comps setDay:1];
            [comps setMonth:1];

            NSDate *yearDate = [gregorian dateFromComponents:comps];

            [where appendFormat:@"zdate > '%@' ",yearDate];

我有一个问题,由记录确定的错误日期,在 sqlite 中核心日期的日期为 2008-01-01 的记录的日期为 1977 年。 如何解决?在查询中使用 NSDate 可能是我错了吗?

【问题讨论】:

    标签: iphone sqlite core-data


    【解决方案1】:

    在某些情况下,您需要将 31 年添加到 SQLite DB 中的日期。

    来自本书:iPhone 取证:恢复证据、个人数据和公司资产 乔纳森·兹齐亚斯基 关于日历事件:

    与大多数时间戳不同 iPhone,这是标准的 Unix 时间戳,这里使用的时间戳 是一个 RFC 822 时间戳,表示 日期偏移到 1977 年。转换 这个日期,确定实际的 RFC 822时间戳,加上31年。

    【讨论】:

      【解决方案2】:

      对于执行任何查询或其他 SQLLite 操作,您应该始终(始终!!!)使用绑定变量。所以查询看起来像:

      zdate > ?
      

      然后你做一个准备好的语句,绑定日期变量,然后执行语句得到你的结果。

      【讨论】:

        【解决方案3】:

        我还没有检查过这个,但在我的脑海中,我猜 sqlite 需要不同的日期格式。考虑使用 NSDateFormatter 将其转换为 sqlite 使用的一个。

        【讨论】:

        • NSDate 使用格式“YYYY-MM-DD HH:MM:SS ±HHMM”; SQLite 接受“YYYY-MM-DD HH:MM:SS”等。我认为除非日期和时间相同,否则时区不会产生影响,尽管 SQLite 中的所有日期都是 UTC 的事实意味着它们不能正确地与本地 NSDates 进行比较(除非你住在 GMT )。
        • 澄清:不同的格式不会对 OP 的查询产生影响。一般来说,它的效果是 NSDate 和 SQLite 日期永远不会相等。
        【解决方案4】:

        谓词中 NSDate 的错误用法!

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date > %@",yearAgo]; - worng
        

        我必须使用这个:

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date > '%f'",[yearAgo timeIntervalSinceReferenceDate];
        

        一切正常。

        【讨论】:

        • 不,它没有。它可能看起来正在工作,但我 100% 确定你有一个指向你的 NSDate 对象的指针的浮点版本!!!
        • 不,我认为这是正确的。 -timeIntervalSinceReferenceDate 返回一个 NSTimeInterval,它的类型定义为加倍,所以他得到了一个正确的浮点数。如果日期作为浮点时间戳存储在数据库中,这应该可以工作。
        猜你喜欢
        • 2010-10-30
        • 2012-03-14
        • 1970-01-01
        • 1970-01-01
        • 2011-06-25
        • 2014-05-19
        • 1970-01-01
        • 2011-02-06
        • 1970-01-01
        相关资源
        最近更新 更多