NSDateFormatter not getting date string parsed - objective-c

This is probably obvious, but I can't seem to convert a date string into an NSDate object. Trying with:
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"HH:mm:ss"];
NSDate *server = [df dateFromString:result];
where result is a c# datetime object converted to a string coming from a webservice. It looks like "12/14/2012 8:00:27 PM". 'server' just keeps coming up as nil.
Also, after i get it to an NSDate, i need to find the difference between 'server' and current time, in hours-minutes-seconds. Should I use NSDateComponents?

[df setDateFormat:#"HH:mm:ss"];
later
where result [...] looks like "12/14/2012 8:00:27 PM"
It certainly doesn't have the format you set, so what do you expect? You have to set the correct format in order to get this working.

Related

NSDateFormatter is adding AM/PM when date format doesn't specify it

I have simple code that transforms a date into a string:
+ (NSString *)dateStringFromDate:(NSDate *)date {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
return [dateFormatter stringFromDate:date];
}
I would expect a string like:
2020-10-19T11:55:29Z
But instead it is outputting a string like this:
2020-10-19T12:38:06 p.m.Z
Note the "p.m." in the output. I am not using the "a" date format character, so I would not expect to see AM or PM.
When I run the code in the simulator, it produces the correct result. When I run it on a physical iPad running iPadOS 14.0.1 it produces the incorrect result.
I have noticed that forcing the locale with this fixes the issue:
dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
But, I'm not sure if that is the correct approach, as this seems like a bug.
Can anyone shed light on why this is happening?

Getting NSDate from time string with UTC format

I am trying to get a NSDate object from a UTC time string. The example of the time string is this:
2016-07-29T11:43:55+02:00
I am usingNSDateFormatter and set the formate as: yyyy-MM-dd'T'HH:mm:ss
However this gives me the take with incorrect time zone. So the above date will be: 2016-07-29T09:43:55+00:00
How do I keep the time zone aspect as well?
I did try adding a 'Z' to the end of the formatter but that just returns a nil date.
Try this
NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];
[userFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSLocale *posix = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[userFormatter setLocale:posix];
NSString *dateConverted = [userFormatter stringFromDate:theDate];
Thanks to all that help. Solved the issue. The time on my iOS Simulator was correct. However when I called [NSDate date]; it show'd me a time two hours before local time. Hence the 'errors' I was seeing in the formatting of NSDate.
Use NSISO8601DateFormatter if targeting iOS 10 and above. https://developer.apple.com/documentation/foundation/nsiso8601dateformatter

parsing date from string, nsdate, objective c

Below is a string represented a date
NSString *dateStr = #"2011-07-06";
And when I am trying to convert it to NSDate by doing :
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"yyyy-MM-dd"];
NSDate *tmp = [format dateFromString:dateStr];
NSLog(#"tmp is %#",[tmp description]);
What I am getting from the console is
tmp is 2011-07-06 04:00:00 +0000
I dont understand why I am getting extra info :04:00:00 +0000 for the result
Please help if you experienced it before
Your code
NSString *dateStr = #"2011-07-06";
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"yyyy-MM-dd"];
NSDate *tmp = [format dateFromString:dateStr]
will result in a NSDate object, that represents your local time at 0:00 — the beginning of the day.
but if you print a plain date object, it will result in a string that represents the time in GMT timezone, as internally all dates are normalized to that timezone.
As your string is 4 hours ahead, we can tell, that you most likely are in East Europe, maybe Moscow.
So if you want to see the string in your timezone, you need to use a NSDateFormatter to create it from the date object.
NSLog(#"tmp is %#",[formatter stringFromDate:tmp]);
to check, if it is correct, what I said, change the format to contain the time components.
formatter.format = [#"yyyy-MM-dd HH:mm"];
NSLog(#"tmp is %#",[formatter stringFromDate:tmp]);
The formatter will also take "oddities" like Leap Day, Leap Month (yes — those exits), Daylight Saving Times, Leap Seconds … in account — accordantly to the current calendar.
A great WWDC 2011 Video: Performing Calendar Calculations — a must-see for every cocoa developer.
BTW: to print a object with NSLog you dont need to call -description on it to pass in a string. NSLog will do this internally.
NSLog(#"tmp is %#", tmp);
is just fine.
The answer is simple, NSLog just converts the NSDate to a NSString, using its formatter with GMT (zero) timezone.
Your formatter is by default set to your default time zone, which is probably -4:00. When you print it out, NSLog converts it to 0:00, adding 4 hours.
In general, it's unsafe to parse dates without specifying their timezone.

How do you convert date time including milliseconds and timezone info to NSDate

I'm trying to convert a string to an NSDate,
however the format always comes out as nil
The date I'm trying to convert is:
2012-08-16T16:20:52.619000+00:00
The date format I'm trying is:
#"yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZ"
If I change the date to:
#"2012-08-16T16:20:52.619000+0000" // removing the : from +00:00
it works a treat, however I would
(I have also tried
#"yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZ:ZZ"
#"yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZ':'ZZ"
but that didn't work either).
Is it even possible to do this without doing string manipulation and removing the final ":"?
I did a final search around this and found out that you have to use
getObjectValue
rather than
dateFromString
In case someone else runs in to this issue, I post my method for converting such strings to NSDate
+ (NSDate *)dateFromString:(NSString *)dateString {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ"];
NSDate *theDate = nil;
NSError *error = nil;
[dateFormat getObjectValue:&theDate forString:dateString range:nil error:&error];
[dateFormat release];
return theDate;
}
It looks like you are using ISO 8601 formatted dates. If you are getting these from a web service, the format changes according to the format. Check this out:
http://boredzo.org/iso8601parser/
This will convert dates according to the format, and even when the format changes slightly.
How about something like
[formatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
the Z has to be in single quotes.

Objective-C - NSTimeZone 2 hours wrong?

I'm using the following code to set my timezone to Stockholm, Europe.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"Europe/Stockholm"]];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm"];
NSDate *webUpdateDate = [dateFormatter dateFromString:#"2011-07-22 22:10"];
// Outputs "2011-07-22 20:10 +0000"
Anyone know why?
I assume you're inspecting the date using NSLog. An NSDate object represents an absolute time -- it has no notion of time zone, so when it is asked for its description, it displays as if it were a time in GMT. If you want that absolute time represented for the Stockholm time zone, you need to use the date formatter again:
NSLog(#"%#", [dateFormatter stringFromDate:webUpdateDate]);
Since the date was originally created via the formatter, which already had its time zone set to Stockholm, I believe this will give you the same string that you used for input: #"2011-07-22 22:10".