如何在Cocoa中获取当前日期

时间:2009-07-01 17:25:18

标签: objective-c cocoa nsdate

我正在开始为iPhone开发,因此我在网上查看不同的教程以及自己尝试一些不同的东西。目前,我正在努力创建一个倒计时,直到午夜。为了获得小时,分钟和秒的数量,我执行以下操作(我在某处找到):

NSDate* now = [NSDate date];

int hour = 23 - [[now dateWithCalendarFormat:nil timeZone:nil] hourOfDay];
int min = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] minuteOfHour];
int sec = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] secondOfMinute];
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, min,sec];

但是,我使用-dateWithCalendarFormat:timeZone:的每个地方都会收到以下错误:

warning: 'NSDate' may not respond to '-dateWithCalendarFormat:timeZone:'
(Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments.)
warning: no '-hourOfDay' method found
error: invalid operands to binary - (have 'int' and 'id')

这看起来很简单。我错过了什么?

另外,我注意到在不同的地方,在不同的时间,星号(*)位于NSDate* now之后或变量NSDate *now之前。这两者有什么区别,为什么你会使用一个与另一个?

14 个答案:

答案 0 :(得分:58)

你有iOS 4.2的问题吗? 使用此代码:

NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"dd.MM.YY HH:mm:ss"];
NSString *dateString = [dateFormatter stringFromDate:currDate];
NSLog(@"%@",dateString);

- > 20.01.2011 10:36:02

答案 1 :(得分:48)

您必须使用以下内容:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit  | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:yourDateHere];
NSInteger hour = [dateComponents hour];
NSInteger minute = [dateComponents minute];
NSInteger second = [dateComponents second];
[gregorian release];

现在NSDate *和NSDate *之间没有区别,这只是一个偏好问题。从编译器的角度来看,没有任何改变。

答案 2 :(得分:21)

您也可以使用:


CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02.0f", currentDate.hour, currentDate.minute, currentDate.second];
CFRelease(currentDate); // Don't forget this! VERY important

我认为这有以下优点:

  1. 没有直接内存分配。
  2. 秒是双倍而不是整数。
  3. 没有留言。
  4. 更快。

答案 3 :(得分:12)

//您可以使用以下代码获取当前日期/时间:

    NSDate* date = [NSDate date];
    NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
    NSTimeZone *destinationTimeZone = [NSTimeZone systemTimeZone];
    formatter.timeZone = destinationTimeZone;
    [formatter setDateStyle:NSDateFormatterLongStyle];
    [formatter setDateFormat:@"MM/dd/yyyy hh:mma"];
    NSString* dateString = [formatter stringFromDate:date];

答案 4 :(得分:5)

替换它:

NSDate* now = [NSDate date];
int hour = 23 - [[now dateWithCalendarFormat:nil timeZone:nil] hourOfDay];
int min = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] minuteOfHour];
int sec = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] secondOfMinute];
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, min,sec];

有了这个:

NSDate* now = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit  | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:now];
NSInteger hour = [dateComponents hour];
NSInteger minute = [dateComponents minute];
NSInteger second = [dateComponents second];
[gregorian release];
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute, second];

答案 5 :(得分:4)

  

另外,我注意到在不同的地方,不同时间,星号(*)位于NSDate* now之后或变量NSDate *now之前。这两者有什么区别,你为什么要使用另一个?

编译器不关心,但在空格之前加上星号可能会产生误导。这是我的例子:

int* a, b;

b的类型是什么?

如果您猜到int *,那就错了。它只是int

另一种方法是通过保持它所属的变量旁边的*来使其更清晰:

int *a, b;

当然,有两种方法比这更清晰:

int b, *a;

int *a;
int b;

答案 6 :(得分:3)

您需要按照以下方式执行某些操作:

NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:now];
NSLog(@"%d", [components hour]);

等等。

答案 7 :(得分:1)

NSDate* nowNSDate *now是一回事:指向NSDate对象的指针。

您可能希望使用 descriptionWithCalendarFormat:timeZone:locale:而不是 dateWithCalendarFormat: - 后者返回NSCalendarDate,文档说计划在某些时候弃用点。

答案 8 :(得分:1)

这是另一种方式:

NSDate *now = [NSDate date];

//maybe not 100% approved, but it works in English.  You could localize if necessary
NSDate *midnight = [NSDate dateWithNaturalLanguageString:@"midnight tomorrow"]; 

//num of seconds between mid and now
NSTimeInterval timeInt = [midnight timeIntervalSinceDate:now];
int hours = (int) timeInt/3600;
int minutes = ((int) timeInt % 3600) / 60;
int seconds = (int) timeInt % 60;

使用NSTimeInterval转换为int会丢失亚秒级精度,但这无关紧要。

答案 9 :(得分:1)

原创海报 - 您确定秒到午夜的方式在夏令时开始或结束的那一天不起作用。这是一段显示如何操作的代码......它将以秒为单位(NSTimeInterval);你可以做除法/模数/等来得到你需要的任何东西。

NSDateComponents *dc = [[NSCalendar currentCalendar] components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:[NSDate date]];
[dc setDay:dc.day + 1];
NSDate *midnightDate = [[NSCalendar currentCalendar] dateFromComponents:dc];
NSLog(@"Now: %@, Tonight Midnight: %@, Hours until midnight: %.1f", [NSDate date], midnightDate, [midnightDate timeIntervalSinceDate:[NSDate date]] / 60.0 / 60.0);

答案 10 :(得分:0)

星号的位置没有区别(在C中,Obj-C基于,无关紧要)。这纯粹是偏好(风格)。

答案 11 :(得分:0)

我花了一些时间来找到示例应用程序的工作原理,但我的工作没有。

作者引用的库(Foundation.Framework)是系统库(来自OS),其中iphone sdk(我使用3.0)不再支持。

因此,示例应用程序(来自about.com,http://www.appsamuck.com/day1.html)可以正常工作,但我们的不适用。

答案 12 :(得分:0)

CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second];

马克是对的,这个代码管理日期小时和秒的效率要高得多。但他忘记了@格式字符串声明的开头。

答案 13 :(得分:0)

+ (NSString *)displayCurrentTimeWithAMPM 
{
    NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
    [outputFormatter setDateFormat:@"h:mm aa"];

    NSString *dateTime = [NSString stringWithFormat:@"%@",[outputFormatter stringFromDate:[NSDate date]]];

    return dateTime;
}

返回凌晨3:33