dateFromString results wrong date - ios

Am Trying to convert NSString to NSDate and then store it on Core Data. I added the timezone to NSDateFormatter still it returns wrong output. And is stored in different format in Core Data.
NSString *dateString=#"2015-09-17 01:06:44";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
dateFormatter.locale = [NSLocale currentLocale];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date_f = [dateFormatter dateFromString:dateString];
NSLog(#"date string %#",dateString);
NSLog(#"date %#",date_f);
NSManagedObject *events=[[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:app.context];
[events setValue:date_f forKey:#"start_date"];
Console Output was
date string 2015-09-17 01:06:44
date 2015-09-16 19:36:44 +0000
Data is stored in Core Data as below
start_date = "September 17, 2015";
Thanks.

This looks like a misunderstanding of time zone conversion. A thing that also gave me some headaches in the past :)
Here is what is done:
You have a date string
You tell that this date string is in local time zone
You convert the string to NSDate
NSDate is now an UTC date because there is no time zone information in a NSDate object
Now, about Core Data and NSManagedObject, you can check this answer. I don't know how your are currently getting this start_date value but first thing is to check you Core Data configuration.
Hope this helps.

Related

Issue with formatting date

I know this question has been asked so many time and may be duplicate of some question, actually i am trying this for storing Date into array by converting them in String. I need that Value in NSDate format so i again convert that stored string into Date.
NSDateFormatter *dateformat = [[NSDateFormatter alloc] init];
[dateformat setDateFormat:#"MM-dd-yy-hh-mm-ss"];
NSString *date = [dateformat stringFromDate:datePicker.date];
[kAppDelegate.glbArrName addObject:date];
But I get this output :
NSString *date = [kAppDelegate.glbArrDate objectAtIndex:indexPath.row];
NSLog(#"Date of birth %#",date);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"MM-dd-yy-hh-mm-ss"];
NSDate *birthDate = [[NSDate alloc] init];
birthDate = [dateFormatter dateFromString:date];
NSLog(#"Date of birth after formatting %#",birthDate);
Output is:
Date of birth 04-05-16-06-38-14
Date of birth after formatting 2016-04-05 01:08:14 +0000
Why it changes format, as i have done same as previous. please help me find out ..
You're rewriting the date string back into an NSDate, then printing out the NSDate, which defaults to the latter 2016-04-05 01:08:14 +0000 format as part of NSDate's -description.

NSDateFormatter return Date in GMT specific timezone

I want to get the date and time in a specific time zone. I am getting most of the things right but just at the end when i get the date from NSString using NSDateFormatter method it returns me the date in the GMT specific time zone. The method [formatter stringFromDate:gmtDate]; return me the expected date and time. The problem happen when i get the date from the string i-e when i execute this method self.localTime = [formatter dateFromString:str];. self.localTime is a NSDate property in my class.
So when i print the str it gives me the date and time in that specific time zone which is represented as self.timeZoneID, which is also a property on my class
NSDate *gmtDate = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:self.timeZoneID]];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *str = [formatter stringFromDate:gmtDate];
NSLog(#"Date string : %#", str);
self.localTime = [formatter dateFromString:str];
Any idea that what could be the reason that i am getting the right string output but when i assign it to my property localTime it give me the time in GMT
Reason is that NSDate have a default time zone that is GMT for consideration and when a user wants to have time specific for some time zone then NSDateFormatter provides way to set specific time zone which you are using for gmtDate object and not for self.localTime(this is taking GMT ,default time zone).

Problems converting a string date to NSDate

I have this string date:
2014-04-21T07:55:13Z
when I convert that to NSDate I have the hour like 6:55... 1 hours less. WHY?
This is the code I am using to convert:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSDate *newDate = [dateFormatter dateFromString:dateStr];
newDate is now 2014-04-21 06:55:13 +0000 !!!???
what is wrong?
NOTE: That one hour less would make sense if the date was my local time (GMT+1) being converted to GMT. But if that Z is zero offset ( = GMT) the date is already GMT.
I don't think your code is wrong. using this code:-
NSString *dateStr = #"2014-04-21T07:55:13Z";
// Convert string to date object
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSDate *date = [dateFormat dateFromString:dateStr];
NSLog(#" date log %#",date); //2014-04-21 02:25:13 +0000 output
// Convert date object to desired output format
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
dateStr = [dateFormat stringFromDate:date];
NSLog(#"string %#",dateStr); //2014-04-21T07:55:13Z output
but NSLog of NSDATE is not output correct according to this NSDate Format outputting wrong date so your code is right.
The NSDate doesn't know anything about formatting (just date information), and the NSDateFormatter doesnt really know anything about dates, just how to format them. So you have to use methods like -stringFromDate: for know that is current or not to actually format the date for pretty human-readable display.
NSLog(#" date is %#",[dateFormat stringFromDate:date]);

SQLite storing, retrieving and comparing a DATETIME field

I am really stuck trying to compare dates in SQLite queries in Objective C. Here's what I'm doing:
Storing the date:
This document tells me to use the dateformat specified below, but it doesn't seem right. I tried using yyyy-MM-dd hh:mm:ss without success too though.
NSDate *today = [NSDate date];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-DD HH:MM:SS"];
NSString *dateString=[dateFormat stringFromDate:today];
NSString *query = [NSString stringWithFormat: #"INSERT INTO user (edited) VALUES (\"%#\")", dateString];
Comparing the date
I am using a timestamp for this, which I convert to a datetime string
long stamp = [sessie integerForKey:#"stamp"];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"YYYY-MM-DD HH:MM:SS"];
NSString *dateString = [formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:stamp]];
sqlite3_stmt *result = [db selectQuery:[NSString stringWithFormat:#"SELECT * FROM user WHERE edited > '%#'", dateString]];
The timestamp is simply generated using [[NSDate date] timeIntervalSince1970]. The problem is that the query won't give the correct results, and I don't even know if the date is stored correctly in the first place. Any help would be greatly appreciated!
A couple of observations:
For your date string, you do definitely do not want to use YYYY-MM-DD HH:MM:SS. That will not generate a valid date string. Using yyyy-MM-dd hh:mm:ss is much closer, but not quite right, either (since you'll use 12-hour hh). Use yyyy-MM-dd HH:mm:ss instead.
This date format, though, does not capture time zone, so, if you store date strings in your SQLite database, you should use UTC (GMT) as discussed in the SQLite Date And Time Functions documentation.
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
formatter.timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
NSString *dateString = [formatter stringFromDate:today];
As shown above, you probably want to also specify the locale so that the format of the dates will not change depending upon the localization settings of the device.
Note that you might consider using timeIntervalSince1970 to store the date as a REAL value in your database (as opposed to a TEXT). This can be a little more efficient and automatically addresses the UTC issue.

Creating NSDate object with specific time zone

I've written a method that accepts a NSDate object and should turn it into a NSDate object with EST time zone. The way I've seen other people accomplish this is by using a date formatter to change the date to a string with the specified time zone. The issue is when I try to change that string back to a NSDate object using "dateFromString".
- (NSDate*)turnToEST:(NSDate*)date
{
NSLog(#"turnToEST called with date %#", date);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"EST"]];
NSString *stringFromDate = [dateFormatter stringFromDate:date];
NSLog(#"date formatted is %#", stringFromDate);
NSDate *dateFromString = [[NSDate alloc] init];
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc]init];
[dateFormatter2 setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
dateFromString = [dateFormatter2 dateFromString:stringFromDate];
NSLog(#"date has been changed to %#", dateFromString);
return date;
}
With output...
turnToEST called with date 2013-12-19 14:15:17 +0000
date formatted is 2013-12-19 09:15:17
date has been changed to 2013-12-19 14:15:17 +0000
I'm not sure why this is any different than
Converting NSString to NSDate (and back again)
NSDate values do not have an associated time zone, they represent an abstract moment in time. So "a NSDate object with EST time zone" isn't a thing that exists. Time zones only come into play when formatting them for output, or trying to do calendar-based math.
NSLog always uses UTC when printing its output.
So you're taking a moment in time, formatting it to a string in a particular time zone, and then parsing it back into the same moment in time. That's working as intended.

Resources