NSDateFormatter returning null on some devices - objective-c

I have problem only with some devices NSDateFormatter returning null the date format from the server is "13:05, 10 November 2013".
NSDate *Now = [NSDate serverDate];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"HH:mm, d MMM yyyy"];
NSDate *LastLogin = [dateFormat dateFromString:DateString];
On simulator and few devices works
LastLogin 2013-10-05 00:36:00 +0000 | Now 2013-11-25 14:50:51 +0000
but on some devices
LastLogin (null) | Now 2013-11-25 15:00:22 +0000

The problem seems to be with locale, just set the locale for the formatter:
NSDate *Now = [NSDate serverDate];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
dateFormat.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormat setDateFormat:#"HH:mm, d MMM yyyy"];
NSDate *LastLogin = [dateFormat dateFromString:DateString];

If you're not setting a particular locale, numbers and dates may be parsed differently even with fixed date formats.
The docs have this to say;
If you're working with fixed-format dates, you should first set the locale of the date formatter to something appropriate for your fixed format. In most cases the best locale to choose is en_US_POSIX, a locale that's specifically designed to yield US English results regardless of both user and system preferences.
Extending your code slightly;
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
NSDate *Now = [NSDate serverDate];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setLocale:enUSPOSIXLocale];
[dateFormat setDateFormat:#"HH:mm, d MMM yyyy"];
NSDate *LastLogin = [dateFormat dateFromString:DateString];

Related

Objective C - Convert DateTime to Local DateTime

I am pretty new to Objective C and it has been horrible experience to get the current device datetime in systemTimeZone. This is what I have:
NSDate *now = [NSDate date];
NSDateFormatter *DateFormatter=[[NSDateFormatter alloc] init];
[DateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[DateFormatter setDateFormat:#"MM-dd-yyyy HH:mm"];
NSString *currentDateTime = [DateFormatter stringFromDate:now];
NSDate *curDate = [DateFormatter dateFromString:currentDateTime];
Line 5 NSString has the correct local datetime in currentDateTime string variable. But Line 6 again switches back to UTC DateTime. I do not understand why it would switch back to UTC even though the DateFormatter has the systemTimezone set. Can you please help me find out what is that I am missing?
Just set the timeZone in the dateFormatter, This code is enough
NSString *dateString = #"24 08 2011 09:45PM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MM yyyy hh:mma"];
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"BST"];
[dateFormatter setTimeZone:sourceTimeZone];
NSDate *dateFromString = [dateFormatter dateFromString:dateString];
The dateFromString will now have the date 24 08 2011 08:45PM(GMT).. Then to convert this to string with local time just code the following,
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone localTimeZone]];
[formatter setLocale:[NSLocale systemLocale]];
[dateFormatter setDateFormat:#"dd MM yyyy hh:mma"];
NSString *stringFromDAte = [dateFormatter stringFromDate:dateString];
or You can also try this one:
NSTimeInterval seconds; // assume this exists
NSDate* ts_utc = [NSDate dateWithTimeIntervalSince1970:seconds];
NSDateFormatter* df_utc = [[[NSDateFormatter alloc] init] autorelease];
[df_utc setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[df_utc setDateFormat:#"yyyy.MM.dd G 'at' HH:mm:ss zzz"];
NSDateFormatter* df_local = [[[NSDateFormatter alloc] init] autorelease];
[df_local setTimeZone:[NSTimeZone timeZoneWithName:#"EST"]];
[df_local setDateFormat:#"yyyy.MM.dd G 'at' HH:mm:ss zzz"];
NSString* ts_utc_string = [df_utc stringFromDate:ts_utc];
NSString* ts_local_string = [df_local stringFromDate:ts_utc];
// you can also use NSDateFormatter dateFromString to go the opposite way
Table of formatting string parameters:
https://waracle.com/iphone-nsdateformatter-date-formatting-table/
If performance is a priority, you may want to consider using strftime
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man3/strftime.3.html

Convert between date formats in Objective-C

I am trying to convert a date into a different format. I'm receiving my date as an NSString with the following format: EEE MMM dd HH:mm:ss ZZZ yyyy, and am attempting to change it to this format: dd-mm-yy. However, I am not able to get it in desired format.
This is my current code:
NSString *dateStr = [NSString stringWithFormat:#"%#",[dict valueForKey:#"createdOn"]];
[dateFormatter setDateFormat:#"EEE MMM dd HH:mm:ss zzz yyyy"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:#"IST"];
dateFormatter.timeZone = gmt;
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
NSDate *dateFromString = [dateFormatter dateFromString:dateStr];
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc] init];
[dateFormatter2 setDateFormat:#"dd/mm/yyyy"];
NSString *newDateString = [dateFormatter2 stringFromDate:dateFromString];
The locale en_US doesn't understand the IST time zone abbreviation. But en_IN does:
NSString *dateStr = #"Tue Mar 24 08:28:48 IST 2015";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEE MMM dd HH:mm:ss zzz yyyy"];
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_IN"];
NSDate *dateFromString = [dateFormatter dateFromString:dateStr];
As John Skeet points out, the issue probably stems from the fact that IST is not unique. IST stands for both Israel Standard Time, and India Standard Time. Thus, when you specify India locale, it makes a reasonable assumption, but for US locale, it is understandably confused.
Unrelated, but make sure to use MM rather than mm in your output formatter:
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc] init];
[dateFormatter2 setDateFormat:#"dd/MM/yyyy"];
NSString *newDateString = [dateFormatter2 stringFromDate:dateFromString];

Change format of date

I got a NSString *string = #"2012-10-24 23:00:00 +0000";
And I want to convert that to a normal format 24 october 2012
I use the following code. But it keeps crashing. Can anyone help me?
NSDateFormatter *dateformat = [[NSDateFormatter alloc] init];
[dateformat setDateFormat:#"yyyy MM dd HH:mm:SS zzz"];
NSDate *dateNS = [dateformat dateFromString:date];
[dateformat setDateFormat:#"dd MM yyyy"];
date = [dateformat stringFromDate:dateNS];
[dateformat release]
It keeps crashing because it can't create the NSDate from the input date because the dateformat is incorrect. it missing the - between the date and the seconds are ss not SS.
Also you need a date formate with MMMM to get the months full name:
NSString *string = #"2012-10-24 23:00:00 +0000";
NSDateFormatter *dateformat = [[NSDateFormatter alloc] init];
[dateformat setDateFormat:#"yyyy-MM-dd HH:mm:ss zzz"];
NSDate *dateNS = [dateformat dateFromString:string];
[dateformat setDateFormat:#"dd MMMM yyyy"];
NSString *date = [dateformat stringFromDate:dateNS];
[dateformat release];

NSString to NSDate returns wrong date

I try to convert my NSString to NSDate object, but NSDateFormatter returns me a strange value.
Here is code:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm"];
NSDate *date = [dateFormat dateFromString:#"2012-08-15 00:00"];
[dateFormat release];
date value is 2012-08-14 21:00 +0000. It is 3 hours difference between NSString value and NSDate value. I think I've missed something, but I don't know what.
This is what i use:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss ZZZ"];
NSDate *date = [dateFormat dateFromString:#"2012-08-15 00:00:00 +0000"];
NSLog(#"\n\n DATE: %# \n\n\n", date);
The +0000 is timezone, so make sure you use your timezone, like +0400.
Edit:
If you can't change the string, you can use this code to do it:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm"];
[dateFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date = [dateFormat dateFromString:#"2012-08-15 00:00"];
As i knew NSDate holds Grinwich time, so if you are in Moscow time zone, everything is wright
In objective c for NSDate if you did not set the setTimeZone, NSDate will take default timezone as localTimeZone. so if you need to get the exact date which you give as NSString string format, you need to setTimeZone as UTC. Follow the sample code, I guess it will be helpful for you.
NSDateFormatter *loacalformatter=[[NSDateFormatter alloc]init];
[loacalformatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *localDate =[loacalformatter dateFromString:#"2012-08-15 00:00"];
NSLog(#"localDate :%#",localDate);
NSDateFormatter *UTCformatter=[[NSDateFormatter alloc]init];
[UTCformatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[UTCformatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *UTCDate =[UTCformatter dateFromString:#"2012-08-15 00:00"];
NSLog(#"UTCDate :%#",UTCDate);
UTCDate :2012-08-15 00:00 +0000 (GMT+00:00)
As suggested in the comments, if the date you receive is UTC then you need to convert it to your local timezone. Apple recommend you always use a properly configured NSDateFormatter when displaying dates, to handle localisation issues.
Here's some example code for turning an NSDate into an NSString:
NSDate *date = // initialised elsewhere
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
dateFormat.locale = [NSLocale currentLocale];
dateFormat.timeZone = [NSTimeZone localTimeZone];
dateFormat.timeStyle = NSDateFormatterShortStyle;
dateFormat.dateStyle = NSDateFormatterShortStyle;
dateFormat.locale = [NSLocale currentLocale];
NSString *dateAsString = [dateFormat stringFromDate:date];

NSDateFormatter in 12-hour mode

I have the following code.
NSDateFormatter *df = ...;
[df setTimeZone:[NSTimeZone defaultTimeZone]];
[df setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZZZ"];
NSDate * date = [df dateFromString:date_string]; //here is the problem
In 24-hour mode everything is ok. When 12-hour mode is set on device, stringFromDate returns null.
Format of date_string is the same all the time, date format too. Why does it happen?
In your NSDateFormatter "yyyy-MM-dd'T'HH:mm:ss.SSSZZZ" HH stands for 24 hour and hh stands for 12 hour
Try to set the locale in this way :
NSLocale *twelveHourLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
df.locale = twelveHourLocale;
To force instead to 24 hour, you can use :
NSLocale *twentyFour = [[NSLocale alloc] initWithLocaleIdentifier:#"en_GB"];
12-hour mode to 24 hour mode:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm a"];
NSDate *amPmDate = [formatter dateFromString:amPmHourString];
[formatter setDateFormat:#"HH:mm"];
NSString *24HourString = [formatter stringFromDate:amPmDate]];
For 24-hour mode to 12 hour mode just do the opposite
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
NSLocale *locale = [[[NSLocale alloc]
initWithLocaleIdentifier:#"en_US_POSIX"] autorelease];
[dateFormat setLocale:locale];