Getting NSDate for today from 00:00:00 as time

I am writing a category in Xcode that extends the current NSDate class. I want to add two methods that I use regularly, and for some reason I cannot get them to work correctly.

I currently have this code:

+ (NSDate*) today { NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *todayComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:[NSDate date]]; NSInteger theDay = [todayComponents day]; NSInteger theMonth = [todayComponents month]; NSInteger theYear = [todayComponents year]; NSDateComponents *components = [[NSDateComponents alloc] init]; [components setDay:theDay]; [components setMonth:theMonth]; [components setYear:theYear]; NSDate* todayDate = [gregorian dateFromComponents:components]; [components release]; [gregorian release]; return todayDate; } 

I want him to return the following date: "2010-11-03 00:00:00 +01". But for some reason, the time zone is holding me, because this code returns "2010-11-02 23:00:00 +0000".

Can someone tell me how to fix this code to actually return the correct date? Or I can just use this date, and my application will convert it itself because of the time zone on which the device is installed.

I need to register certain events in my application in a database that also just uses the [NSDate date] method. Does this mean that the [NSDate date] method also uses time without time zone information?

EDIT: I think this has something to do with daylight saving time error. What I see is exactly the same as probably the Clock application, with an error causing people to wake up late. In addition, TimeZone by default uses the TimeZone installed on your device, so it should remain unchanged until you change the time zone on the settings screen.

EDIT2: Ok, a few more tests:

 NSLog(@"CurrentDate: %@", [NSDate date]); NSLog(@"TZ: %@", [NSTimeZone defaultTimeZone]); 

Gives me the following results:

 2010-11-03 23:23:49.000 App[8578:207] CurrentDate: 2010-11-03 22:23:49 +0000 2010-11-03 23:23:49.001 App[8578:207] TZ: Europe/Amsterdam (GMT+01:00) offset 3600 
+6
ios objective-c iphone cocoa
source share
5 answers

See Using Time Zones . You want to set the time zone of the calendar using the NSCalendar -setTimeZone: method before you start asking for dates.

+5
source share

This is an interesting question, and I worked a lot on the solution. These are my findings:

 NSLog(@"CurrentDate: %@", [NSDate date]); 

The code shown above will have the same result as the code shown below:

 NSLog(@"CurrentDate: %@", [[NSDate date] description]); 

Reading with NSDate Class Reference gives this documentation using the NSDate description method.

Constant performance in different versions of the operating system is not guaranteed. To format a date, use the date formatting object instead (see NSDateFormatter Guide and Data Formatting Guide).

I also looked at the documentation for descriptionWithLocale: (id) locale :

"Returns a string representation of the receiver using this language."

So change your code

 NSLog(@"CurrentDate: %@", [NSDate date]); 

To:

 NSLog(@"CurrentDate: %@", [[NSDate date] descriptionWithLocale:[NSLocale currentLocale]]); 

Which should lead to what you are looking for. And I can also prove that [NSDate date] does give the correct date, but just displays with the wrong method:

We can use [today] (Wim Haanstra) to create two dates.

dateLastDay : 2010-11-02 23:59:00 +01
dateToday : 2010-11-03 24:01:00 +01

Then we use the following code to show two dates:

 NSLog(@"CurrentDate: %@", dateLastDay); NSLog(@"CurrentDate: %@", dateToday); 

Or:

 NSLog(@"CurrentDate: %@", [dateLastDay description]); NSLog(@"CurrentDate: %@", [dateToday description]); 

Two groups show the same results: "2010-11-02 22:59:00 +0000" and "2010-11-02 23: 01: 00 +0000". It seems that the two dates have the same "day", but really?

Now we compare the days of the dates:

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSUInteger unitFlags = NSDayCalendarUnit; NSDateComponents *lastDayComponents = [gregorian components:unitFlags fromDate:dateLastDay]; NSDateComponents *todayComponents = [gregorian components:unitFlags fromDate:dateToday]; NSInteger lastDay = [lastDayComponents day]; NSInteger today = [todayComponents day]; return (lastDay == today) ? YES : NO; 

We will get NO! Although the two dates seem to have the same day, month, and year, they DO NOT. This only appears because we displayed them wrongly.

+3
source share

You tried to use:

 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd"]; todayAtOO = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]]; 
+2
source share

I'm still trying to figure out why this error is occurring, but I know the solution. Setting the time zone of your NSCalendar to GMT before sending it to dateFromComponents: solves the problem.

 [gregorian setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]]; 

PS, if there is another solution that you found based on Joshua’s proposal, could you tell us what it is? It looks like you solved the problem because you accepted his answer, but it is not entirely clear what you did. Thanks!

+1
source share

As far as I can see, it gives the correct answer if your time zone is GMT + 1. Midnight is your time 23:00 on the eve of GMT.

Probably the problem is formatting the return date for output. This gave you a string for GMT instead of your current locale.

0
source share

All Articles