NSDateFormatter Error - objective-c

I wrote a code block
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US"];
[dateFormatter setDateFormat:#"YYYY-MM-dd"];
NSLog(#"date:%#,string:%#", aDate,[dateFormatter stringFromDate:aDate]);
it works well for most date, but if the date is 2013-12-30 it works strange .
the Log string is date:2013-12-30 16:00:00 +0000,string:2014-12-31
Why? why the date 2013-12-30 convert to string is 2014-12-31?

The NSDate you're giving it is 4pm in GMT. You're probably not in GMT, so it's formatting that time/date for your current timezone, where it's at least eight hours later.
Create your NSDate with the local timezone, or use NSDateComponents if you really want just a date with no time.

Related

objective c convert string to UTC- the time is moving in error

I return a string from my database and value is '04/27/2016 1:16pm'. This value is already in UTC.
Now I want to convert that string to NSDATE, keeping it in UTC. When I try to convert string to date, the time is actually moving by 1 hour.
This is how I am doing it
NSString *tuploadtime = [tempDictionary valueForKey:#"uploadTime"];
//date conversions
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM-dd-yyyy HH:mm:ss a"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSDate *duploadtime = [[NSDate alloc] init];
duploadtime = [dateFormatter dateFromString:tuploadtime];
NSLog(#"tuploadtime=%#, duploadtime=%#", tuploadtime, duploadtime);
the result is coming back as 2016-04-27 12:16:01 UTC.
result is
2016-04-27 10:12:44.612 x[1558:48608] tuploadtime=4/27/2016 2:10:33 PM, duploadtime=2016-04-27 12:10:33 +0000
basically the time is moving back 1 hour but I want to keep it the same.
hope I am making sense
Proper String Format for Date is most Important.
There are some methods to have HOURS format as follow with their differences..
kk: will return 24 format Hour in (01-24) hours will (look like 01, 02..24).
HH will return 24 format Hour in (00-23) hours will(look like 00, 01..23).
hh will return 12 format Hour (look like 01, 02..12).
so you should use your code like
NSString *tuploadtime = [tempDictionary valueForKey:#"uploadTime"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM-dd-yyyy hh:mm:ss a"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSDate *duploadtime = [[NSDate alloc] init];
duploadtime = [dateFormatter dateFromString:tuploadtime];
NSLog(#"tuploadtime=%#, duploadtime=%#", tuploadtime, duploadtime);
for More Date format refer this link
Your date format string is inconsistent:
[dateFormatter setDateFormat:#"MM-dd-yyyy HH:mm:ss a"];
HH means to use a 24-hour format. But then you also used a to indicate AM/PM. Using both is confusing the formatter and giving you off-by-one. You meant to use hh here.

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.

NSDateFormatter dateFromString with date

i have a problem with method dateFromString, here is my code
NSString* res = [NSString stringWithFormat:#"%#/%#/%#",dateInput.text,monthInput.text,yearInput.text];
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
[formatter setTimeZone:[NSTimeZone localTimeZone]];
[formatter setDateFormat:#"dd/MM/yy"];
NSDate* inpTime = [formatter dateFromString:res];
[dateResult setText:[NSString stringWithFormat:#"%#",inpTime]];
when I run, the date in "inpTime" always is "dateInput" - 1.
for example: if "dateInput" is 5, the date in "inpTime" will be 4
You need to adjust the timezone.
Change
[formatter setTimeZone:[NSTimeZone localTimeZone]];
to
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
This is because you're not setting the time, so it's set by default the midnight UTC.
But when you are displaying the date with a timezone other than UTC the time is shifted accordingly.
As an example if you live in New York the 12/29/2012 00:00:00 UTC is actually the 12/28/2012 18:00:00 for you.
You Code is perfect, no error what so ever.
Try nslogging dateInput.text, monthInput.text and yearInput.text...might be from here you are getting invalid data.

Why isn't my time zone being saved into my NSDate?

I must initialize an NSDate object from NSString in objective-c. I do it like this:
NSString *dateString = [[webSentence child:#"DateTime"].text stringByReplacingOccurrencesOfString:#"T" withString:#" "];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-mm-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"Europe/Budapest"]];
NSDate *date = [[NSDate alloc] init];
date = [dateFormatter dateFromString:dateString];
E.g: when I try it with string value #"2011-01-02 17:49:54" I get an NSDate 2011-01-02 16:49:54 +0000. As you can see there is a one hour difference between the two values. NSDate has a wrong value, it should be exactly the same I defined in my string in the timezone I set in dateFormatter. It seems it uses my date defined it string as UTC, even if I set its timezone to "Europe/Budapest". How can I fix this problem?
Thanks!
NSDate stores dates relative to a standard reference date. From the class docs:
"The sole primitive method of NSDate, timeIntervalSinceReferenceDate, provides the basis for all the other methods in the NSDate interface. This method returns a time value relative to an absolute reference dateā€”the first instant of 1 January 2001, GMT."
NSDate does not itself have any concept of time zones. So the NSDateFormatter did the right thing: it converted a date which you told it had a GMT offset (by specifying a time zone), and gave you a "normalized" NSDate for that date.
If you want to see the date represented in the Europe/Budapest time zone, either use your existing date formatter (-stringFromDate:) or the appropriate NSDate description method (e.g. -descriptionWithCalendarFormat:timeZone:locale:).
P.S.- You don't need an alloc/init at all in your code as written. In non-ARC that would be a leak.
P.P.S.- Your date format is incorrect and giving nonsensical results. I've gone ahead and cleaned up your code as follows (tested under ARC):
NSString *dateString = #"2011-09-02 17:49:54";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *tz = [NSTimeZone timeZoneWithName:#"Europe/Budapest"];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:tz];
NSDate *date = [dateFormatter dateFromString:dateString];
NSLog(#"%#", [dateFormatter stringFromDate:date]);
NSLog(#"%#", [date descriptionWithCalendarFormat:nil timeZone:tz locale:nil]);
Two things:
1) you have an error in your date format string. You should use MM for month, not mm (lowercase mm is for minutes)
2) after you create you NSDate object, you'll need to use the NSDateFormatter method stringFromDate: to generate a date string localized to a particular timezone. If you just do a straight NSLog() on the NSDate object it will show the date as GMT by default (GMT is one hour behind Budapest time)

Create NSDate timezone issue

I am loading in dates from my web service, I'm sending dates in the format (GMT times): 02/11/11 10:56:09
I am creating an NSDate form this using NSDateFormatter as such:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
NSDate *journeyDate = [dateFormatter dateFromString:str];
[dateFormatter release];
This works great, after I'm comparing this to the current date to get relative time intervals.
The problem is when the phone is set up in a different timezone, when I load in the date from my api, and use the date formatter, what seems to be happening is the phone is assuming the date string is local time and it's converting it to GMT.
Example:
I load in a date with the time 10am from the api.
The phone is set to PDT.
The date formatter is creating an NSDate assuming that my date string with 10am, is actually relevant to the phone.
I end up with a date and time equal to 5pm, adding 10 hours.
I am trying to specify in my date formatter that the string is GMT, but I'm having trouble, I've tried the following, adding GMT to the format:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy HH:mm:ss GMT"];
NSDate *journeyDate = [dateFormatter dateFromString:str];
[dateFormatter release];
This is not working.
Can anyone give any advice ?
Solution
Just a recap, I got it working with a terrible work around by appending GMT to the original string, and formatting that:
NSString * cheat = [NSString stringWithFormat:#"%# GMT", str];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy HH:mm:ss zzzz"];
NSDate *journeyDate = [dateFormatter dateFromString:cheat];
[dateFormatter release];
return journeyDate;
This was a kind of unstable hack, because if the string changed to include a timezone, it wouldn't work anymore. For anyone who needs to do as myself, the following is just a quick example on how to create an NSTimeZone.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSDate *journeyDate = [dateFormatter dateFromString:str];
[dateFormatter release];
return journeyDate;
Thanks for the quick help.
I suspect you just want to use NSDateFormatter.setTimeZone to force it to use UTC. You don't want to change the format string because presumably the string doesn't include the letters "GMT" - instead, you want to change which time zone the string is interpreted in, which is what setTimeZone will do.
You should use the setTimeZone method: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html