Cocoa NSDate:一天中正确的工作方式?

Cocoa NSDate:一天中正确的工作方式?,cocoa,cocoa-touch,time,nsdate,Cocoa,Cocoa Touch,Time,Nsdate,我正在使用一个指定一天时间的时间表,例如上午10:30。不过,我不知道日期。我将把它们作为值存储在NSDictionary中,并希望以一种简单的方式处理它们 我不能使用NSDate,因为我没有日期。至少,不是以直截了当的方式 另一种明显的方式是NSTimeInterval,但这可能是非常微妙的错误的来源。我特别想到了夏令时(出于某种原因,本周我一直在考虑夏令时) 除此之外,唯一真正让人想到的是将其保存在格式化字符串中,或将其编码为NSNumber(如hours*60+minutes)。当然,这两

我正在使用一个指定一天时间的时间表,例如上午10:30。不过,我不知道日期。我将把它们作为值存储在
NSDictionary
中,并希望以一种简单的方式处理它们

我不能使用
NSDate
,因为我没有日期。至少,不是以直截了当的方式

另一种明显的方式是
NSTimeInterval
,但这可能是非常微妙的错误的来源。我特别想到了夏令时(出于某种原因,本周我一直在考虑夏令时)

除此之外,唯一真正让人想到的是将其保存在格式化字符串中,或将其编码为
NSNumber
(如
hours*60+minutes
)。当然,这两种方法都很好,但看起来我正在发明一个方轮,我确信在那里已经有一个圆轮了


使用Cocoa处理原始时间的最简单方法是什么?

您可以只存储所需的组件(例如小时和分钟),然后使用
NSCalendar
创建绝对日期引用,当您需要使用序列化组件和基准日期时。

简单的回答是,没有内置的机制来存储一天中的时间,所以只需使用您最方便的方式即可。我过去使用过字符串,使用我自己的编码和解析代码(例如,“22:00”),因为它们易于阅读和调试,但按照您的建议存储午夜后的秒或分钟并没有什么错。记住,你必须自己做数学题

无论您如何操作,都需要单独的年、月、日、小时、分钟和秒值,以便使用NSCalendar的
-dateFromComponents:
方法从NSDateComponents构建NSDate


正如其他人所说,您不能通过向现有的
NSDate
添加小时和分钟来设置一天中的时间,因为如果您跨越DST边界,您将无法获得预期的值。(但是,我假设您仍然可以添加日和月组件,而不必担心DST)

因此,我想没有简单的内置方法来实现这一点。看起来让Cocoa在DST边界上构建预期时间的唯一方法是使用字符串

所以对于后代来说,看起来我会用这样的东西

测试线束:

//
//  TimeTest.m
//

#import <Foundation/Foundation.h>

#import "Utility.h"

id utility;

void testTime( NSTimeInterval time ) {
    id gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];

    id oneDay = [[[NSDateComponents alloc] init] autorelease];
    [oneDay setDay: 1];

    id thisDay = [gregorian dateFromComponents: [gregorian components: (NSEraCalendarUnit | NSYearCalendarUnit)
                                                             fromDate: [NSDate date]]];
    for (NSInteger dayIdx = 0; dayIdx < 365; ++dayIdx ) {
        NSDate *dateTime = [utility timeInSeconds: time
                                           onDate: thisDay];
        NSLog( @"%@", dateTime );

        thisDay = [gregorian dateByAddingComponents: oneDay
                                             toDate: thisDay
                                            options: 0];
    }
}



int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    utility = [[[Utility alloc] init] autorelease];

    testTime( ((10 * 60.0) + 0.0) * 60.0 );
    testTime( ((9 * 60.0) + 30.0) * 60.0 );

    [pool drain];
    return 0;
}
//
//时间测试
//
#进口
#导入“Utility.h”
id实用程序;
无效测试时间(NSTimeInterval时间){
id gregorian=[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]自动释放];
id oneDay=[[NSDateComponents alloc]init]autorelease];
[一天固定日:1];
id thisDay=[gregorian dateFromComponents:[gregorian components:(NSEraCalendarUnit | NSYearCalendarUnit)
fromDate:[NSDate日期]];
对于(NSInteger dayIdx=0;dayIdx<365;++dayIdx){
NSDate*dateTime=[实用程序时间顺序:时间]
日期:今天];
NSLog(@“%@”,日期时间);
thisDay=[gregorian dateByAddingComponents:一天
托德:今天
选项:0];
}
}
int main(int argc,const char*argv[]{
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
实用程序=[[utility alloc]init]autorelease];
测试时间(((10*60.0)+0.0)*60.0);
测试时间(((9*60.0)+30.0)*60.0);
[泳池排水沟];
返回0;
}
实用程序标题:

//
//  Utility.h
//

#import <Foundation/Foundation.h>


@interface Utility : NSObject {
    NSCalendar *gregorian;
    NSDateFormatter *dateWithoutTimeFormatter, *dateWithTimeFormatter;
}

- (NSDate *)timeInHours: (NSInteger)hours
                minutes: (NSInteger)minutes
                seconds: (NSInteger)seconds
                 onDate: (NSDate *)inDate;

- (NSDate *)timeInSeconds: (NSTimeInterval)inTime
                   onDate: (NSDate *)inDate;

@end
//
//公用事业
//
#进口
@接口实用程序:NSObject{
NSCalendar*格里高利;
NSDateFormatter*dateWithoutTimeFormatter,*dateWithTimeFormatter;
}
-(NSDate*)时间小时:(NSInteger)小时
分钟:(NSInteger)分钟
秒:(NSInteger)秒
onDate:(NSDate*)inDate;
-(NSDate*)TIMEINSONDS:(NSTIMEIVAL)inTime
onDate:(NSDate*)inDate;
@结束
实用程序实现:

//
//  Utility.m
//

#import "Utility.h"


@interface Utility()
@property (nonatomic, readwrite, retain) NSCalendar *gregorian;
@property (nonatomic, readwrite, retain) NSDateFormatter *dateWithoutTimeFormatter, *dateWithTimeFormatter;
@end



@implementation Utility



@synthesize gregorian, dateWithoutTimeFormatter, dateWithTimeFormatter;



- (NSDate *)timeInHours: (NSInteger)hours
                minutes: (NSInteger)minutes
                seconds: (NSInteger)seconds
                 onDate: (NSDate *)inDate;
{
    id timeStr = [[NSMutableString alloc] initWithFormat: @"%02d:%02d:%02d", hours, minutes, seconds];
    id dateStr = [dateWithoutTimeFormatter stringFromDate: inDate];
    id dateTimeStr = [[NSString alloc] initWithFormat: @"%@ %@", dateStr, timeStr];
    [timeStr release];
    id dateTime = [dateWithTimeFormatter dateFromString: dateTimeStr];
    [dateTimeStr release];
    return dateTime;
}



- (NSDate *)timeInSeconds: (NSTimeInterval)inTime
                   onDate: (NSDate *)inDate;
{
    NSAssert1( inTime < 24.0 * 3600.0, @"Time %f must be less than 24hrs", inTime );

    double temp = inTime;
    int hours = rintf(floor( temp / 3600.0 ));
    temp -= ( hours * 3600 );
    int minutes = rintf(floorf( temp / 60.0 ));
    temp -= ( minutes * 60 );
    int seconds = rintf( temp );

    return [self timeInHours: hours
                     minutes: minutes
                     seconds: seconds
                      onDate: inDate];
}



- (id)init;
{
    if (( self = [super init] )) {
        self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];
        self.dateWithoutTimeFormatter = [[[NSDateFormatter alloc] init] autorelease];
        [dateWithoutTimeFormatter setDateFormat: @"yyyy-MM-dd"];
        self.dateWithTimeFormatter = [[[NSDateFormatter alloc] init] autorelease];
        [dateWithTimeFormatter setDateFormat: @"yyyy-MM-dd HH:mm:ss"];
    }
    return self;
}



- (void)dealloc;
{
    self.gregorian = nil;
    self.dateWithoutTimeFormatter = nil;
    self.dateWithTimeFormatter = nil;
    [super dealloc];
}



@end
//
//公用事业公司
//
#导入“Utility.h”
@接口实用程序()
@财产(非原子、读写、保留)NSCalendar*公历;
@属性(非原子、读写、保留)NSDateFormatter*dateWithoutTimeFormatter、*dateWithTimeFormatter;
@结束
@实现实用程序
@合成格里高利,dateWithTimeFormatter,dateWithTimeFormatter;
-(NSDate*)时间小时:(NSInteger)小时
分钟:(NSInteger)分钟
秒:(NSInteger)秒
onDate:(NSDate*)inDate;
{
id timeStr=[[NSMutableString alloc]initWithFormat:@“%02d:%02d:%02d”,小时、分钟、秒];
id dateStr=[dateWithoutTimeFormatter stringFromDate:inDate];
id dateTimeStr=[[NSString alloc]initWithFormat:@“%@%@”,dateStr,timeStr];
[timeStr发布];
id dateTime=[dateWithTimeFormatter dateFromString:dateTimeStr];
[dateTimeStr发布];
返回日期时间;
}
-(NSDate*)TIMEINSONDS:(NSTIMEIVAL)inTime
onDate:(NSDate*)inDate;
{
NSAssert1(时间<24.0*3600.0,@“时间%f必须小于24小时”,时间);
双温度=初始时间;
整小时=rintf(地板温度/3600.0));
温度-=(小时*3600);
整数分钟=整数英尺(地板(温度/60.0));
温度-=(分钟*60);
int秒=rintf(温度);
返回[自拍时间]小时数
分钟:分钟
秒:秒
onDate:inDate];
}
-(id)init;
{
if((self=[super init])){
self.gregorian=[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]autorelease];
self.datewithout timeformatter=[[NSDateFormatter alloc]init]autorelease];
[dateWithoutTimeFormatter setDateFormat:@“yyyy-MM-dd”];
self.dateWithTimeFormatter=[[[NSDateFormatter alloc]init]autorelease];