2009-07-01 33 views
55

我正在开始为iPhone开发,因此我在网上查看不同的教程以及尝试一些不同的东西。目前,我正在尝试创建一个倒计时,直到午夜。要获得的小时,分​​钟和秒,我做了以下的数量(这是我发现的地方):每一个地方我用-dateWithCalendarFormat:timeZone:我如何获得可可的当前日期

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]; 

不过,我得到以下错误:

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之前。两者有什么区别,为什么你会使用一个与另一个?

回答

47

您必须使用以下方法:

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的没有什么区别,它只是一个偏好的问题。从编译器的角度看,没有任何变化。

+0

你为什么要使用NSCalendar这是最近的更改?有很多代码使用NSDate来处理这些事情。 – Jason 2009-07-01 17:40:04

+0

是的,许多方法现在已被弃用。 – 2009-07-01 17:51:00

+2

杰森:NSDate依然存在。您使用NSCalendarDate(这就是-dateWithCalendarFormat:时区:收益),并计划弃用,并在iPhone上不存在。 – 2009-07-02 02:32:33

0

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

2

NSDate* nowNSDate *now是一样的东西:指向NSDate对象的指针。

你可能想使用descriptionWithCalendarFormat:时区:区域:而不是dateWithCalendarFormat: - 后者返回一个NSCalendarDate,该文件说计划在某个时候被弃用。

3

你需要沿着以下的线路做一些事情:

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

等。

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,但是这不应该的问题。

+0

第二次看,iPhone SDK可能没有 - (NSDate)dateWithNaturalLanguageString:(NSString *)str方法,所以这可能是一个Leopard/Tiger唯一的解决方案。对不起 – 2009-07-01 19:40:53

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

    Opps忘记在你的stringWithFormat上加“@”。无论如何感谢这一点。 – andsien 2011-12-14 09:37:41

    +0

    你必须释放来自CFTimeZoneCopySystem()返回的引用,否则你会得到一个内存泄漏。 – brutella 2012-07-31 07:53:40

    4

    Also, I've noticed at different places and at different times the asterisk (*) is located either right after the time NSDate* now or right before the variable NSDate *now . What is the difference in the two and why would you use one versus the other?

    编译器不关心,而是把星号的空间之前,可能会产生误导。这里是我的例子:

    int* a, b; 
    

    b是什么类型的?

    如果你猜int *,你错了。这只是int

    另一种方式使这通过保持稍微更清晰的*旁边的变量属于:

    int *a, b; 
    

    当然,也有两种方式都比更加清晰:

    int b, *a; 
    
    int *a; 
    int b; 
    
    +0

    是的,这是一个很好的参数:总是附加*到变量名;或从不在同一行上声明两个变量。就我个人而言,由于我更喜欢​​将“指向”作为该类型的一部分,所以我选择了后一种解决方案,但人们一定要意识到这个问题。 – 2009-07-02 03:15:05

    0

    我花了一段时间来找出为什么示例应用程序可以工作,但我的不知道。

    ,作者参考图书馆(Foundation.Framework)是系统库(从OS),其中iPhone的SDK(我用3.0)不支持任何更多。

    因此示例应用程序(从about.com,http://www.appsamuck.com/day1.html)的作品,但我们没有。

    +0

    Foundation仍然是iPhone SDK的一部分。你真的不能没有它。缺少的是NSCalendarDate,它从来没有在iPhone上可用(据我所知)。 – 2009-08-15 18:22:53

    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]; 
    
    0
    CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem()); 
    countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second]; 
    

    马克是正确的验证码是更有效的管理日期小时分和秒。但是他在格式字符串声明的开头忘记了@。

    57

    您有iOS 4.2的问题? > 2011年1月20日10时36分02秒

    1

    原来的海报 - - 夏令时开始,当你确定秒钟,直到午夜的方式不会在日常工作

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

    : 使用此代码或结束。下面是一段代码,它显示了如何做到这一点...它将以秒为单位(一个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); 
    
    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

    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];