How to get local date and time? - objective-c

I am using NSDate to get current time and date but it is giving date and time based on GMT.Please can anyone know how to get local time?
Thanks in advance!

NSDate has no knowledge of timezones. It always stores dates as absolute moments in time, in GMT.
Use NSDateFormatter to get a local (or any other time zone) representation.
See the pertinent programming guide: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html

[dateFormatter setTimeZone:systemTimeZone];
set the timezone of the date using a date formatter with the above method. It will work. Convert the date to string, set the format and timezone and convert back to date.

Hi I found this from another site
NSDate* sourceDate = [NSDate date];
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate] autorelease];
Link for the website is here

Related

NSDate is wrong when doing 'dateFromString'

Im here in the UK and when working with dates in iOS they are always out by one hour (one hour behind), what I need is the correct time from an NSDate. Ive done the following, but i get two different times:
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSLog(#"NSDate %#",today);
NSLog(#"Time %#", [dateFormatter stringFromDate:today]);
NSDate*stringDate = [dateFormatter dateFromString:[dateFormatter stringFromDate:today]];
NSLog(#"Time date %#",stringDate);
Here is what is logged:
NSDate 2015-07-01 16:07:22 +0000
Time 2015-07-01 17:07:22
Time date 2015-07-01 16:07:22 +0000
Why is this happening? Am i missing something obvious? Surely if the string date is correct, then doing dateFromString should yield the correct results?
The reason I need an NSDate is so I can get the correct amount of seconds using [myTime timeIntervalSince1970]
2015-07-01 17:07:22 //is the correct date
Im expecting an NSDate object that is correct to my date and time.
Update
The answers below helped me find where I was going wrong, so I changed my approach, I was able to get the current timestamp doing the following:
NSString *timeStamp = [dateFormatter stringFromDate:[NSDate date]];
NSDate *curdate = [dateFormatter dateFromString:timeStamp];
int unix_timestamp = [curdate timeIntervalSince1970];
NSDate* referenceDate = [NSDate dateWithTimeIntervalSince1970: 0];
NSTimeZone* timeZone = [NSTimeZone systemTimeZone];
int offset = (int)[timeZone secondsFromGMTForDate: referenceDate];
int currentTimestamp = unix_timestamp + offset;
NSLog(#"CUrrent time stamp %d",currentTimestamp);
NSDate is an absolute moment of time, it does not have a timezone. The date object you have is correct: it is exactly the moment that code was executed.
If you need string representation of that moment of time in a specific time zone, use stringFromDate: just like you did.
If you need to know number values of hour/minute in a specific time zone, use -[NSCalendar components:fromDate:].
[calendar setTimeZone:...];
NSDateComponents* components = [calendar components:(NSHourCalendarUnit|NSMinuteCalendarUnit) fromDate:date];
The date formatter defaults to the local timezone. If you want a different timezone specify it. NSLog of a date used the 'NSDatedescription` method that defaults to GMT (UTC).
Examining the code:
NSDate *today = [NSDate date];
// Creates today's data in GMT (UTC) All NSDates are referenced to GMT.
NSLog(#"NSDate %#",today); (moved up for explanation ordering)
// NSDate 2015-07-01 16:07:22 +0000
// Displays the date in GMT
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
// Creates a date for matter with the system timezone
NSLog(#"Time %#", [dateFormatter stringFromDate:today]);
// Time 2015-07-01 17:07:22
// Creates a string representation in the system timezone and displays it
NSDate*stringDate = [dateFormatter dateFromString:[dateFormatter stringFromDate:today]];
// Creates a date from the string taking into the system timezone
NSLog(#"Time date %#",stringDate);
// Time date 2015-07-01 16:07:22 +0000
// Displays the date in GMT.

Converting any date to local date issue

I am stuck somewhere in NSDate and NSDateFormatter due to timezone issues.
I need to send time to server only in UTC(which is converted to unix time).
Here is my few steps what I am doing:
Selecting a date from the calender should be added with the current time and converted to UTC.
Compare the selected date with the current date. Just to know whether selected date is a past or future date. (Few other operations are to be done based on past/future/current date).
I have tried this code:
In a Category on NSDate :
-(NSDate *) toLocalTime{
NSDate* sourceDate = self;
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithName:#"UTC"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];
return destinationDate;
}
But the problem exists when I try to convert date to local, (at times I am not sure the current time is in local timezone or not). If they are in UTC then the above method works fine.
If the time is already in local timezone then it again adds the interval and I am getting incorrect time.
I am out of ideas, please help me.
Any idea will be highly appreciated.
NSDate represents the time since Jan 1st 1970 in UTC. Never try to pretend it is anything else. Never try to think of an NSDate as being in a particular local time.
So what you need is a date from a calendar + an offset which represents the time since midnight today.
To get today 0:00am UTC, you first need a Gregorian calendar for the UTC time zone.
NSTimeZone* utcTimeZone = [NSTimeZone timeZoneWithName:#"UTC"];
NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
[gregorian setTimeZone: utcTimeZone];
Now you use date components to get the hours, minutes and seconds since midnight UTC
NSUInteger unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDate *date = [NSDate date];
NSDateComponents *comps = [gregorian components: unitFlags fromDate:date];
If you have a date that is midnight UTC on the date from your calendar, you can get midnight UTC + your hours, minutes and seconds like this:
NSDate* theDateIWant = [gregorian dateByAddingComponents: comps
toDate: midnightUTCDateFromCalendar
options: 0];
NSLog(#"The final date is %#", theDateIWant);

NSDate issue.. Incorrect time? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
NSDate not returning correct date
when I try to display current time like so:
NSDate *mydate = [NSDate date];
I get this result:
2012-11-24 09:27:13.194 myApp[5284:c07] mydate = 2012-11-24 07:27:13 +0000
the time is off by two hours although the simulator time and OS X time is different. How can I fix that? Thank you in advance..
You need to print out the date with an NSDateFormatter. NSDate doesn't have any timezone information attached to it. Make sure to attach a timezone to your date formatter.
NSDate* now = [NSDate date];
// GET A DATE FORMATTER AND SET THE TIMEZONE
NSDateFormatter *df = [[NSDateFormatter alloc] init];
df.timeZone = [NSTimeZone systemTimeZone];
// CHANGE FORMAT TO SUIT YOUR NEEDS
[df setDateStyle: NSDateFormatterFullStyle];
[df setTimeStyle: NSDateFormatterFullStyle];
// GET YOUR FORMATTED DATE STRING
NSString *dateString = [df stringFromDate: now];

current Date and Time - NSDate

I need to display the current Date and Time.
I have used ;
NSDate *currentDateNTime = [NSDate date];
I want to have the current date and time (Should display the system time and not GMT time).
The output should be in a NSDate format and not NSString.
for example;
NSDate *currentDateNTime = [NSDate date];
// Do the processing....
NSDate *nowDateAndTime = .....; // Output should be a NSDate and not a NSString
Since all NSDate is GMT referred, you probably want this:
(don'f forget that the nowDate won't be the actual current system date-time, but it's "shifted", so if you will generate NSString using NSDateFormatter, you will see a wrong date)
NSDate* currentDate = [NSDate date];
NSTimeZone* currentTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSTimeZone* nowTimeZone = [NSTimeZone systemTimeZone];
NSInteger currentGMTOffset = [currentTimeZone secondsFromGMTForDate:currentDate];
NSInteger nowGMTOffset = [nowTimeZone secondsFromGMTForDate:currentDate];
NSTimeInterval interval = nowGMTOffset - currentGMTOffset;
NSDate* nowDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:currentDate];
Every moment in time is the same moment in time everywhere around the world —- it is just expressed as different clock times in different timezones. Therefore, you can't change the date to some other date that represents the time in your timezone; you must use an NSDateFormatter that you feed with the timezone you are in. The resulting string is the moment in time expressed in the clock time of your position.
Do all needed calculations in GMT, and just use a formatter for displaying.
Worth reading
Does [NSDate date] return the local date and time?
Some useful resources for anyone coming to this more recently:
Apple date and time programming guide do read it if you're doing anything serious with dates and times.
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DatesAndTimes/DatesAndTimes.html#//apple_ref/doc/uid/10000039i?language=objc
Useful category on NSDate with lots of utilities does allow a ~new~ date to be generated based on an existing date.
https://github.com/erica/NSDate-Extensions
There's also a swift version of the category
https://github.com/erica/SwiftDates
You need an NSDateFormatter and call stringFromDate this method to get a string of your date.
NSDateFormatter *dateformater = [[NSDateFormatter alloc] init];
[dateformater setDateFormat:#"yyyyMMdd,HH:mm"];
NSString *str = [dateformater stringFromDate: currentDateNTime];
use this method
-(NSDate *)convertDateToDate:(NSDate *) date
{
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
NSDate *nowDate = [[[NSDate alloc] init] autorelease];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setDateFormat:#"yyyy-MM-d H:m:s"];
NSString * strdate = [formatter stringFromDate:date];
nowDate = [formatter dateFromString:strdate];
return nowDate;
}
this may return you what you want.
i hope you this may help you.

Getting date from [NSDate date] off by a few hours

I am using
NSDate *date = [NSDate date];
for getting the date, but the date I get is off by 2 hours.
NSDate objects don't have time zones. They represent an absolute moment in time. However, when you ask one for its description (by printing it with NSLog(), e.g.), it has to pick a time zone. The most reasonable "default" choice is GMT. If you're not in GMT yourself, the date will seem to be incorrect, by the amount of your own offset.
You should always use an NSDateFormatter to create a string for display. The formatter's timezone should be set to yours, which is the default.
You can get your date corrected like this:
NSDate * dateGMT = [NSDate date];
NSTimeInterval secondsFromGMT = [[NSTimeZone localTimeZone] secondsFromGMT];
NSDate * correctDate = [dateGMT dateByAddingTimeInterval:secondsFromGMT];
-(NSDate *)getDateInCurrentSystemTimeZone
{
NSDate* sourceDate = [NSDate date];
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];
return destinationDate;
}