Bug When Trying to Parse Date in Objective-C

Convert String to Date in Objective-C

You are correctly parsing the string to the Date object. The way it is presented by the print is because by default if printing an object, its description is printed. In case of Date, it will be always the format you get. But the date is correct.

If you want to get it presented the way it was before, again use the same dateFormatter and just format the date to string back:

NSLog(@"result date: %@", [df stringFromDate:resultDate]);

UPDATE

If the problem is the hour shift, that's due to your current timezone that will be used when parsing using DateFormatter. To overcome this, set explicitly timezone and locale of the date formatter, see this example (swift version, but you need just those two line with setting timeZone and locale on dateFormatter):

let dateString = "3/2/2018 11:44:32 AM"

let df = DateFormatter()
df.dateFormat = "MM/d/yyyy h:mm:ss a"

// set the timezone and locale of the dateformatter:
df.timeZone = TimeZone(identifier: "GMT")
df.locale = Locale(identifier: "en_US_POSIX")

let date = df.date(from: dateString)

// now it will print as you expect:
print(date)

I have a bug when parsing an array of dates

You are converting dates without specifying a time zone, so your local one is assumed. After a little research at a guess you're in Brazil in the time zone of Sao Paulo, Campo Grande or Cuiba - Nov 2 2004 is when daylight savings changed in those locations and 0000 didn't exist as time jumped to 0100.

If you are just after the date conversion you can set the time zone to UTC (which has no daylight savings), add:

formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];

and you won't get null for that date.

Parsing JSON dates on IPhone

As a .NET programmer learning Objective-C I had the same problem when I tried to consume a .Net WebService.

At first I thought I would be able to use the NSDateFormatter...
I found a really good reference for it's symbols here, but I quickly realized that I needed to convert the number from milliseconds to seconds.

I wrote the code to do it...
I'm still learning Obj-C but I dont think It should've been this hard...

- (NSDate *) getJSONDate{
NSString* header = @"/Date(";
uint headerLength = [header length];

NSString* timestampString;

NSScanner* scanner = [[NSScanner alloc] initWithString:self];
[scanner setScanLocation:headerLength];
[scanner scanUpToString:@")" intoString:×tampString];

NSCharacterSet* timezoneDelimiter = [NSCharacterSet characterSetWithCharactersInString:@"+-"];
NSRange rangeOfTimezoneSymbol = [timestampString rangeOfCharacterFromSet:timezoneDelimiter];

[scanner dealloc];

if (rangeOfTimezoneSymbol.length!=0) {
scanner = [[NSScanner alloc] initWithString:timestampString];

NSRange rangeOfFirstNumber;
rangeOfFirstNumber.location = 0;
rangeOfFirstNumber.length = rangeOfTimezoneSymbol.location;

NSRange rangeOfSecondNumber;
rangeOfSecondNumber.location = rangeOfTimezoneSymbol.location + 1;
rangeOfSecondNumber.length = [timestampString length] - rangeOfSecondNumber.location;

NSString* firstNumberString = [timestampString substringWithRange:rangeOfFirstNumber];
NSString* secondNumberString = [timestampString substringWithRange:rangeOfSecondNumber];

unsigned long long firstNumber = [firstNumberString longLongValue];
uint secondNumber = [secondNumberString intValue];

NSTimeInterval interval = firstNumber/1000;

return [NSDate dateWithTimeIntervalSince1970:interval];
}

unsigned long long firstNumber = [timestampString longLongValue];
NSTimeInterval interval = firstNumber/1000;

return [NSDate dateWithTimeIntervalSince1970:interval];
}

Hopefully someone can provide a better Obj-C solution.
If not I may keep this or look for a way to change the serialization format in .NET

EDIT:

About that JSON DateTime format...
If you have any control on the service it would probably be best to convert the date to a string in your DataContract objects.

Formatting to RFC1123 seems like a good idea to me right now. As I can probably pick it up easily using a NSDateFormatter.

Quote from Rick Strahl

There's no JavaScript date literal and Microsoft engineered a custom date format that is essentially a marked up string. The format is a string that's encoded and contains the standard new Date(milliseconds since 1970) value.

Error when converting date string to NSObject

The error occurs because the date format is wrong and the date string cannot be converted.

Please try to understand the format. The date string contains day (d), month (M) and year (y) slash separated – or month (M), day (d) and year (y) - but there is no letter T, no hyphens (-), no hours (H), no minutes (m), no seconds (s), no milliseconds (S), no timezone (Z) and no am/pm

The format is @"dd/MM/yyyy" or @"MM/dd/yyyy"

And why are you converting string to date and then immediately back to string?

If you want to convert dd/MM/yyyy to ISO8601 you need two different formats for input and output

NSString *val = @"09/08/1987";
NSDateFormatter *_dateFormatter = [[NSDateFormatter alloc] init];
_dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
_dateFormatter.dateFormat = @"dd/MM/yyyy";
NSDate *date = [_dateFormatter dateFromString:val];
_dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZZZ";
NSString *convertedString = [_dateFormatter stringFromDate:date];

Getting incorrect date from 24 hours format time string in Objective C and iOS

The output is correct.

A date string without year / month / day information causes a date 2000/1/1 in NSDateFormatter.

You need to get the current date and replace the hour and minute components with those of the date string.

NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *todayComponents = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
[formatter setDateFormat:@"HH:mm"];
NSDate *myDate = [formatter dateFromString:@"13:54"];
NSDateComponents *myDateComponents = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate:myDate];
todayComponents.minute = myDateComponents.minute;
todayComponents.hour = myDateComponents.hour;
NSDate *myCompleteDate = [calendar dateFromComponents:todayComponents];

Date/Time parsing in iOS: how to deal (or not deal) with timezones?

I don't know how right this is, but I ultimately found that in .NET I have to do DateTime.ToUniversalTime().ToString("yyyy-MM-ddHH:mm:ss") and on the iOS side I have to do this:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
[dateFormatter setDateFormat:@"yyyy-MM-ddHH:mm:ss"];
NSDate *date = [dateFormatter dateFromString:@"2011-04-0600:28:27"];

Only then is the date correct when NSLog outputs, so I'm assuming that I've finally got a proper date/time.

How to parse a date string into an NSDate object in iOS?

You don't need near as many single quotes as you have (only needed on non date/time characters), so change this:

[self.dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];

To this:

[self.dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZ"];
...
self.currentQuestion.updated = [self.dateFormatter dateFromString:[self.currentParsedCharacterData stringByReplacingOccurrencesOfString:@":" withString:@"" options:0 range:NSMakeRange([self.currentParsedCharacterData length] – 5,5)]];

Documentation here: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW1

Unicode Format Patterns: http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns

Dealing with TimeZones with Colons (+00:00): http://petersteinberger.com/2010/05/nsdateformatter-and-0000-parsing/



Related Topics



Leave a reply



Submit