From string with locale to date on iphone sdk - iphone

I trying to find a way to convert a string into a date with a given locale identifier.
I have for example an italian date (locale: it_IT) I want to convert into a valid date object.
NSDate *GLDateWithString(NSString *string, NSString *localeIdentifier) {
[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier];
[formatter setLocale:locale];
[locale release];
NSDate *date = [formatter dateFromString:string];
[formatter release];
return date;
}
this code does not work, the date is nil.
I can't figure out how I should use the locale setting for my purpose.

The solution is to use getObjectValue:forString:range:error: method of NSDateFormatter and set the correct date and time style ad follow:
- (NSDate *)dateWithString:(NSString *)string locale:(NSString *)localeIdentifier {
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeStyle:NSDateFormatterNoStyle];
[formatter setDateStyle:NSDateFormatterShortStyle];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier];
[formatter setLocale:locale];
[locale release];
NSDate *date = nil;
NSRange range = NSMakeRange(0, [string length]);
NSError *error = nil;
BOOL converted = NO;
converted = [formatter getObjectValue:&date forString:string range:&range error:&error];
[formatter release];
return converted? date : nil;
}
example:
NSString *italianDate = #"30/10/2010";
NSString *italianLocale = #"it_IT";
NSDate *date = [myCustomFormatter dateWithString:italianDate locale:italianLocale];

I struggled with German formats as well sometime ago and solved the problem by supplying my own formatting string:
[formatter setDateFormat:#"dd.MMM.yyyy HH:mm:ss"];
Then:
[dateFormatter dateFromString:#"01.Dez.2010 15:03:00"];
will get a correct NSDate.

Related

How to get the localized day of an NSDate as string?

I have an NSDate object and must create a label that indicates the day of the week in a short 3-char style like 'Mon', 'Tue', 'Wed', ... and localized to the short representation in any language.
The date formatter EEE has 3 chars but how does that translate to languages like Chinese which probably only have one character?
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"EEE"];
NSString *strDate = [formatter stringFromDate:date];
[formatter release];
//Commented out the following line as weekday can be of one letter (requirement changed)
//strDate = [strDate substringToIndex:3]; //This way Monday = Mon, Tuesday = Tue
To use the correct locale you'll want to set the dateFormat on the instance of NSDateFormatter using the + dateFormatFromTemplate:options:locale: method.
NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = [NSDateFormatter dateFormatFromTemplate:#"EEE" options:0 locale:[NSLocale currentLocale]];
NSLog(#"Weekday using %#: %#", [[NSLocale currentLocale] localeIdentifier], [dateFormatter stringFromDate:date]);
// Test what Chinese will look like without changing device locale in settings
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"zh_CN"];
NSLog(#"Weekday using zh_CN: %#", [dateFormatter stringFromDate:date]);
This prints:
Weekday using en_US: Thu
Weekday using zh_CN: 周四
This will print what you need:
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"EEEE"];
NSString *day = [formatter stringFromDate:date];
[formatter release];
if ([day length] > 3) day = [day substringToIndex:3];
NSLog(#"%#", day);

Converting a value into NSDate

I have this ticks value "634758517020305000" which corresponds to 21st June 2012. I tried to convert the tick value into NSDate object like this:
NSString *str = #"634758517020305000";
NSInteger offset = [[NSTimeZone defaultTimeZone] secondsFromGMT];
NSDate *date = [[NSDate dateWithTimeIntervalSince1970:
[[str substringWithRange:NSMakeRange(0, [str length])] intValue]]
dateByAddingTimeInterval:offset];
static NSDateFormatter *dateFormatter = nil;
if (dateFormatter == nil) {
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
NSString *fourDigitYearFormat = [[dateFormatter dateFormat] stringByReplacingOccurrencesOfString:#"yy" withString:#"yyyy"];
[dateFormatter setDateFormat:fourDigitYearFormat];
}
// There you have it:
NSString *outputString = [dateFormatter stringFromDate:date];
But I got the output: 1/19/2038. If anyone knows where I am doing wrong, please let me know.
your Unix timestamps is wrong. it should be 1340236800
check your Unix timestamps Here

Need help for specific date format

I have next date string,
2011-08-30T11:44:54.345-04:00
Help me to compose right format to parse it with dateFromString:
You need to eliminate the last colon (timezone, "-04:00" -> "-0400"), as Z will take something like "-0800", then you can give this a try:
NSString *dateString = #"2011-08-30T11:44:54.345-04:00";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-ddEHH:mm:ss.SSSZ"];
NSDate *date = [dateFormat dateFromString:dateString];
[dateFormat release];
For more information on date formatting, refer to this page.
This is following the tilo's answer but with few things added.
NSString *dateString = #"2011-08-30T11:44:54.345-04:00";
NSRange range = [dateString rangeOfString:#":" options:NSBackwardsSearch];
dateString = [dateString stringByReplacingOccurrencesOfString:#":" withString:#"" options:0 range:range];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-ddEHH:mm:ss.SSSZ"];
NSDate *date = [dateFormat dateFromString:dateString];
[dateFormat release];
You would get the required format.

NSDateFormatter - getObjectValue:forString:range:error: returns incorrect date

I am trying to convert from an NSString to NSDate using getObjectValue:forString:range:error:. The function returns success and no errors, but the returned date is incorrect.
Specifically, I am passing #"1989-12-31T00:00:00+00:00" to the function below and the returned date is 1970-01-01 00:00:000 +0000. Any thoughts?
+ (NSDate *) convertStringToDate:(NSString *) dateString
{
NSDate* date = nil;
NSError* error = nil;
NSRange range = NSMakeRange(0, [dateString length]);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
BOOL success = [dateFormatter getObjectValue:&date forString:dateString range:&range error:&error];
[dateFormatter release];
return success ? date : nil;
}
Thanks in advance.
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:locale];
[dateFormatter setLocale:usLocale];
[usLocale release];
[dateFormatter setDateFormat:#"EEE, dd MMMM yyyy HH:mm:ss Z"];
NSDate *date = [dateFormatter dateFromString:dateString];
Notes:
Get locale for NSLocale init from source you're getting this date like RSS feed or similar.
setDateFormate: adjust to format of your source.

How to handle different date time formats using NSDateFormatter

I have a String with a datetime format: "YYYY-MM-DD HH:MM:SS".
I use this in my source code:
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"%e. %B %Y"];
NSString *test = [formatter stringFromDate:#"2010-01-10 13:55:15"];
I want to convert from "2010-01-10 13:55:15" to "10. January 2010".
But my implementation does not work.
What's wrong here?
Thanks a lot in advance & Best Regards.
Updated source code:
[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"%Y-%m-%d %H:%M:%S"];
NSString *test1 = [formatter stringFromDate:#"2010-01-10 13:55:15"];
NSDateFormatter *formatter1 = [[[NSDateFormatter alloc] init] autorelease];
[formatter1 setDateFormat:#"%d. %M4 %Y"];
NSString *test2 = [formatter1 stringFromDate:test1];
A date formatter can only handle one format at a time. You need to take this approach:
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [f dateFromString:#"2010-01-10 13:55:15"];
NSDateFormatter *f2 = [[NSDateFormatter alloc] init];
[f2 setDateFormat:#"d. MMMM YYYY"];
NSString *s = [f2 stringFromDate:date];
s will now be "10. January 2010"
Here are a few examples of working with data formatters from my code. You should be able to take any one of these functions and tweak it for your format.
USAGE
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [Constants getTitleDateFormatter];
NSString *dateString = [dateFormatter stringFromDate:today];
[dateFormatter release];
FUNCTIONS
+ (NSDateFormatter *) getDateFormatterWithTimeZone {
//Returns the following information in the format of the locale:
//YYYY-MM-dd HH:mm:ss z (Z is time zone)
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[NSLocale currentLocale]];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
[dateFormatter setTimeStyle:NSDateFormatterLongStyle];
return dateFormatter;
}
+ (NSDateFormatter *)dateFormatterWithoutYear {
NSDateFormatter *dateFormatter = [Constants getDateFormatterWithTimeZone];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSString *format = [dateFormatter dateFormat];
format = [format stringByReplacingOccurrencesOfString:#"/yy" withString:#""];
NSRange secondSpace;
secondSpace.location = format.length-2;
secondSpace.length = 1;
format = [format stringByReplacingCharactersInRange:secondSpace withString:#""];
[dateFormatter setDateFormat:format];
return dateFormatter;
}
+ (NSDateFormatter *) dateFormatterMonthDayOnly {
NSDateFormatter *dateFormatter = [Constants getDateFormatterWithTimeZone];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSString *format = [dateFormatter dateFormat];
format = [format stringByReplacingOccurrencesOfString:#"/yy" withString:#""];
NSRange range;
range.location = 0;
range.length = 3;
format = [format substringWithRange:range];
[dateFormatter setDateFormat:format];
return dateFormatter;
}
+ (NSDateFormatter *) getTitleDateFormatter {
//Returns the following information in the format of the locale:
//MM-dd-yyyy hh:mm:ssa
NSDateFormatter *dateFormatter = [Constants getDateFormatterWithTimeZone];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
NSString *format = [dateFormatter dateFormat];
NSRange secondSpace;
secondSpace.location = format.length-2;
secondSpace.length = 1;
format = [format stringByReplacingOccurrencesOfString:#"/" withString:#"-"];
format = [format stringByReplacingCharactersInRange:secondSpace withString:#""];
[dateFormatter setDateFormat:format];
return dateFormatter;
}
First off, make sure you set the behavior to 10.4 - more modern, works better in my experience.
[dateTimeFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
Next, you can't use the same format to parse and format if they have 2 different string representations, so use 2 formatters, or change the string format between parsing and then formatting.
Also make sure you consider the formatting options:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW1
lowercase is e is the day of week, lowercase d is the day of the month.
For month, use MMMM, not B.
You want to use [NSFormatter dateFromString:] to convert your string-based date to an NSDate instance. From there you want to use stringFromDate with the NSDate, not the string as you have written above. I'm not sure about using the same NSDateFormatter for both parsing and formatting - you may need two separate instances to handle the different format styles.