繁体   English   中英

创建没有时间元素的日期的NSDate最佳实践

[英]NSDate best practice in creating a date with no time element

我正在编写一个使用核心数据来存储我的数据的应用程序。 其中包括一个日期字段,我只对日期而不是时间感兴趣。 我需要根据日期(而不是时间)选择记录,因此我在NSDate上创建了一个类别以返回日期,标准化为设定时间,如下所示:

+ (NSDate *)dateWithNoTime:(NSDate *)dateTime {
if( dateTime == nil ) {
    dateTime = [NSDate date];
}
NSDateComponents* comps = [[NSCalendar currentCalendar] components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:dateTime];
NSDate *dateOnly = [[NSCalendar currentCalendar] dateFromComponents:comps];
[dateOnly dateByAddingTimeInterval:(60.0 * 60.0 * 12.0)];           // Push to Middle of day.
return dateOnly;

}

然后我在将数据添加到核心数据存储时使用它(我有一个使用此方法设置原始日期值的setter)然后我使用此方法创建一个日期,用于比较执行日期时的日期获取请求。 所以在理论上这应该总是有效 - 即挑出我正在寻找的日期。

我有点紧张,因为我不完全确定改变时区或地区会有什么影响。 它还能用吗?

仅当您对时间不感兴趣时​​,在日期存储和搜索时,最佳做法是什么。

干杯。

编辑

阅读推荐的讨论后,我认为我应该修改我的代码如下。 我的想法是,如果我确保将其推送到特定日历系统和特定时区(UTC),那么无论您在设置日期和阅读日期时的位置,日期都应始终相同。 对此新代码的任何评论都表示赞赏。

+ (NSDate *)dateWithNoTime:(NSDate *)dateTime {
if( dateTime == nil ) {
    dateTime = [NSDate date];
}

NSCalendar       *calendar   = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[calendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
                         fromDate:dateTime];

NSDate *dateOnly = [calendar dateFromComponents:components];

[dateOnly dateByAddingTimeInterval:(60.0 * 60.0 * 12.0)];           // Push to Middle of day.
return dateOnly;

}

你有几个问题要处理。 首先,正如您所说,时区。 您还需要担心夏令时,这会改变“正午”的概念。

看一下关于CocoaDev的讨论 ,Apple Engineer给出了一些答案并讨论了一些最佳实践。

更简单的解决方案是使用查找某个范围内的日期的谓词。

使用NSCalendarComponent为“day”创建开始日期和结束日期,然后在谓词中包含这些日期和结束日期。

NSPredicate *p=[NSPredicate predicateWithFormat:@"$@ <= date <= $@",startDate,endDate];

这将提供最大的灵活性,而不会太复杂。 编程的日期和时间看似复杂。 准备做一些工作。

我最终还是在一个场景中我需要有一个NSDate来比较一个日期而不考虑时间。

我喜欢过滤机制,作为UI的一部分,如果用户今天选择最小日期作为开始日期和结束日期为今天,我将显示“所有时间段”而不是格式的字符串:

1/5/2006 - 2009年12月24日

所以我需要使用NSDate +date来获取今天的日期,并将其与结束日期进行比较。 该结束日期来自UIDatePicker设置为没有时间,但+date返回现在的日期和时间。

所以我写了这个简短的方法,它接收一个日期对象,使用NSDateComponentsNSCalendar类来提取日,月和年。

然后使用NSDateFormatter's dateFromString:方法将这3个参数用于创建新的NSDate ,结果是NSDate对应于与参数date相同的“日期”(在传统的人类概念中)但没有时间。

- (NSDate *)strictDateFromDate:(NSDate *)date{
    NSUInteger flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
    NSDateComponents *components = [[NSCalendar currentCalendar] components:flags
                                                                   fromDate:[NSDate date]];
    NSString *stringDate = [NSString stringWithFormat:@"%d/%d/%d", components.day, components.month, components.year];

    NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
    formatter.dateFormat = @"dd/MM/yyyy";

    return [formatter dateFromString:stringDate];
}

我希望你将来可以使用和享受这个功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM