所以,我想有這樣的沒有簡單的內置方式。它也看起來像讓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
//
#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
實用工具實現:
//
// 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
爲什麼用這個獨立的單元煩惱呢?那麼,我已經寫了足夠的日期格式代碼,知道在飛行中構建NSCalendar
和NSDateFormatter
會徹底殺死性能。
不幸的是,這會在調整時鐘的日子返回錯誤的結果。在2010年3月14日上午11:00至上午9點,在2010-11-07上午9點加上十個小時。我大概可以作弊並讓我的時間相對於凌晨4點或其他時間,但是我會對日曆做一個愚蠢的假設。 (iPhone報警錯誤的可能原因?) – 2010-11-02 20:19:37
啊,是的,這似乎是iPhone報警錯誤的可能來源。哦,不過,這值得嘗試。 :-) – 2010-11-02 20:24:08
是的。當一個真正的好主意行不通時,這是非常不方便的。但謝謝你的嘗試。 :) – 2010-11-02 20:29:19