[objective-c] How do I get the current date in Cocoa

I'm getting started developing for the iPhone and as such I am looking at different tutorials online as well as trying some different things out myself. Currently, I'm trying to create a countdown until midnight. To get the number of hour, minutes, and seconds, I do the following (which I found somewhere):

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

However, each place I use -dateWithCalendarFormat:timeZone: I get the following error:

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')

This seems like something very simple. What am I missing?

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?

This question is related to objective-c cocoa nsdate

The answer is


It took me a while to locate why the sample application works but mine don't.

The library (Foundation.Framework) that the author refer to is the system library (from OS) where the iphone sdk (I am using 3.0) is not support any more.

Therefore the sample application (from about.com, http://www.appsamuck.com/day1.html) works but ours don't.


Here's another way:

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;

You lose subsecond precision with the cast of the NSTimeInterval to an int, but that shouldn't matter.


You have problems with iOS 4.2? Use this Code:

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


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

Mark was right this code is MUCH more efficient to manage dates hours min and secs. But he forgot the @ at the beginning of format string declaration.


Replace this:

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

With this:

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

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?

The compiler doesn't care, but putting the asterisk before the space can be misleading. Here's my example:

int* a, b;

What is the type of b?

If you guessed int *, you're wrong. It's just int.

The other way makes this slightly clearer by keeping the * next to the variable it belongs to:

int *a, b;

Of course, there are two ways that are even clearer than that:

int b, *a;

int *a;
int b;

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

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

    return dateTime;
}

return 3:33 AM


There is no difference in the location of the asterisk (at in C, which Obj-C is based on, it doesn't matter). It is purely preference (style).


Original poster - the way you're determining seconds until midnight won't work on a day when daylight savings starts or ends. Here's a chunk of code which shows how to do it... It'll be in number of seconds (an NSTimeInterval); you can do the division/modulus/etc to get down to whatever you need.

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

// you can get current date/time with the following code:

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

NSDate* now and NSDate *now are the same thing: a pointer to an NSDate object.

You probably want to use descriptionWithCalendarFormat:timeZone:locale: rather than dateWithCalendarFormat: — the latter returns an NSCalendarDate, which the docs say is scheduled to be deprecated at some point.


You need to do something along the lines of the following:

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

And so on.


You can also use:


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

I think this has the following advantages:

  1. No direct memory allocation.
  2. Seconds is a double instead of an integer.
  3. No message calls.
  4. Faster.

Examples related to objective-c

Adding a UISegmentedControl to UITableView Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Warp \ bend effect on a UIView? Use NSInteger as array index Detect if the device is iPhone X Linker Command failed with exit code 1 (use -v to see invocation), Xcode 8, Swift 3 ITSAppUsesNonExemptEncryption export compliance while internal testing? How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem? Change status bar text color to light in iOS 9 with Objective-C

Examples related to cocoa

How to update a single pod without touching other dependencies How to initialise a string from NSData in Swift Input from the keyboard in command line application Get current NSDate in timestamp format Xcode build failure "Undefined symbols for architecture x86_64" Cocoa Autolayout: content hugging vs content compression resistance priority setValue:forUndefinedKey: this class is not key value coding-compliant for the key iOS - Build fails with CocoaPods cannot find header files Get Current date & time with [NSDate date] Remove all whitespaces from NSString

Examples related to nsdate

Get current date in Swift 3? How to get time (hour, minute, second) in Swift 3 using NSDate? Convert string to date in Swift Date Format in Swift How to convert string to date to string in Swift iOS? Getting the difference between two Dates (months/days/hours/minutes/seconds) in Swift Get day of week using NSDate Get UTC time and local time from NSDate object How can I convert string date to NSDate? How do you create a Swift Date object?