对 Cococa NSDate 的彻底失望

Posted

技术标签:

【中文标题】对 Cococa NSDate 的彻底失望【英文标题】:Total frustration about Cococa NSDate 【发布时间】:2012-03-16 15:04:37 【问题描述】:

我完全搞砸了 NSDate 课程

我正在做一个计划应用程序,您可以在其中按日期计划

我只需要知道时间表是 5.3.2011 13:45(在每个时区)就是这样(如果您打开应用程序并且当地时间是 5.3.2011 13:40,您会看到“在 5分钟”,无论您的时区是 GMT+5 还是 GMT+8)...

但由于 NSDate 存储的是 TIME MOMENT,而不是日期(如班级名称所述),我遇到了几个问题

1) NSDate 不存储保存它的时区,这意味着如果我有一个日期 5.3.2011 13:45 我不知道是 GMT0 还是 GMT +1(比当地时间 5.3.2011 14:45)

2) 我无法比较两个 NSDate 是否在同一天(如 9 月 7 日),因为它们可以在不同的时区(因为日期代表一个时间点,在一个区域内,这个时间点对应于一天, 在另一个时区到另一个)

怎么办?

我找到了类似的方法

-(NSDate *) dateToLocalTime

    NSTimeZone *tz = [NSTimeZone defaultTimeZone];
    NSInteger seconds = [tz secondsFromGMTForDate: self];
    return [NSDate dateWithTimeInterval: seconds sinceDate: self];


-(NSDate *) dateToGlobalTime

    NSTimeZone *tz = [NSTimeZone defaultTimeZone];
    NSInteger seconds = -[tz secondsFromGMTForDate: self];
    return [NSDate dateWithTimeInterval: seconds sinceDate: self];

但没有按预期工作

因为他们使用了

NSTimeZone *tz = [NSTimeZone defaultTimeZone];
NSInteger seconds = -[tz secondsFromGMTForDate: self]; 

这意味着必须将日期保存在 defaultTimezone 中才能正常工作

【问题讨论】:

什么不符合他们的预期? 因为他们使用 NSTimeZone *tz = [NSTimeZone defaultTimeZone]; NSInteger seconds = -[tz secondsFromGMTForDate: self];这意味着必须将日期保存在 defaultTimezone 中才能正常工作 听起来你还没有发现NSCalendar 您只能将 nsdate 与核心数据一起存储 您的问题是什么? NSDate 完全没问题,你只需要了解日历的概念。 【参考方案1】:

这个帖子 (http://www.cocoabuilder.com/archive/cocoa/278456-nsdate-without-time-portion.html) 帮了我很多

我会将日期存储在字符串中,因此 15.7.2011 15:30,无论您在哪个时区,都保持 15.7.2011 15:30

static NSDateFormatter * formatter = nil;

- (NSDate *) reminderLocalDate

    if (formatter == nil) 
        NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"YYYYMMDD"];
        [formatter setTimeZone:[NSTimeZone localTimeZone]];
    
    //[formatter setTimeZone:[NSTimeZone localTimeZone]];
    return [formatter dateFromString:self.reminder];


- (void) setReminderWithLocalDate:(NSDate *)date

    if (formatter == nil) 
        NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"YYYYMMDD"];
        [formatter setTimeZone:[NSTimeZone localTimeZone]];
    

    self.reminder = [formatter stringFromDate:date];

甚至更好,将它们存储在 NSNumber 中,例如 20110411,这样我就可以使用 运算符

- (NSNumber *) toDNumber

    unsigned int unitFlags = NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit;
    NSDateComponents * dc = [[NSCalendar currentCalendar] components:unitFlags fromDate:self];
    return [NSNumber numberWithInt:dc.year * 10000 + dc.month * 100 + dc.day];


+ (NSDate *) dateWithDNumber:(NSNumber *)number

    NSDateComponents * dc = [[NSDateComponents alloc] init];

    int num = [number intValue];
    dc.year = num / 10000;
    num = num % 10000;

    dc.month = num / 100;
    num = num % 100;

    dc.day = num;

    return [[NSCalendar currentCalendar] dateFromComponents:dc];

【讨论】:

以上是关于对 Cococa NSDate 的彻底失望的主要内容,如果未能解决你的问题,请参考以下文章

一文让你彻底弄懂MySQL自增列

人总要彻底的绝望一次 才能脱胎换骨涅槃重生

Java面试题,这一次带你搞懂Spring代理创建过程,一招彻底弄懂!

需要彻底替换对 std::copy 的可能不安全的调用

一文彻底解决新手对webpack的恐惧!

Linux下彻底卸载LibreOffice方法